package gu.sql2java.transformer;

import java.io.File;
import java.lang.reflect.Array;
import java.lang.reflect.GenericArrayType;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Modifier;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.lang.reflect.TypeVariable;
import java.lang.reflect.WildcardType;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URL;
import java.net.URLClassLoader;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.sql.Timestamp;
import java.util.AbstractMap.SimpleImmutableEntry;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Date;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.NavigableMap;
import java.util.NavigableSet;
import java.util.Map.Entry;
import java.util.Set;
import java.util.SortedMap;
import java.util.SortedSet;
import java.util.TreeMap;
import java.util.TreeSet;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.ConcurrentNavigableMap;
import java.util.concurrent.ConcurrentSkipListMap;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicLong;
import java.util.concurrent.locks.ReentrantReadWriteLock;

import com.gitee.l0km.aocache.annotations.AoWeakCacheable;

import com.google.common.base.Function;
import com.google.common.base.Functions;
import com.google.common.base.Optional;
import com.google.common.base.Predicate;
import com.google.common.base.Throwables;
import com.google.common.collect.BiMap;
import com.google.common.collect.FluentIterable;
import com.google.common.collect.HashBasedTable;
import com.google.common.collect.ImmutableBiMap;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableListMultimap;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableMultimap;
import com.google.common.collect.ImmutableMultiset;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.ImmutableSetMultimap;
import com.google.common.collect.ImmutableSortedMap;
import com.google.common.collect.ImmutableSortedMultiset;
import com.google.common.collect.Iterables;
import com.google.common.collect.ListMultimap;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.collect.Multimap;
import com.google.common.collect.Multiset;
import com.google.common.collect.SetMultimap;
import com.google.common.collect.Maps.EntryTransformer;
import com.google.common.collect.Sets;
import com.google.common.collect.SortedMultiset;
import com.google.common.collect.Table;
import com.google.common.collect.Table.Cell;
import com.google.common.primitives.Booleans;
import com.google.common.primitives.Bytes;
import com.google.common.primitives.Chars;
import com.google.common.primitives.Doubles;
import com.google.common.primitives.Floats;
import com.google.common.primitives.Ints;
import com.google.common.primitives.Longs;
import com.google.common.primitives.Primitives;
import com.google.common.primitives.Shorts;
import com.google.common.reflect.TypeParameter;
import com.google.common.reflect.TypeToken;
import com.google.common.util.concurrent.AtomicDouble;

import gu.sql2java.relection.ParameterizedTypeImpl;
import gu.sql2java.relection.WildcardTyper;
import gu.sql2java.transformer.TransformerContext.LocalContext;

import static com.google.common.base.Functions.compose;
import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.base.Preconditions.checkArgument;
import static gu.sql2java.utils.DateSupport.TIMESTAMP_FORMATTER_STR;
import static gu.sql2java.utils.DateSupport.formatDate;
import static gu.sql2java.utils.DateSupport.getDateFromString;
import static gu.sql2java.relection.ParameterizedTypeImpl.of;

/**
 * 类型转换工具类[线程安全]，类型转换工具类,copy from common-basex 4.4.0<br>
 * 该类提供了一些常用的转换函数，包括基本类型之间的转换、数组、集合类型之间的转换,以及一些特殊类型之间的转换，可以直接使用，也可以增加自定义转换函数，增加扩展转换功能。<br>
 * <ul>
 * <li>基本类型之间的转换：{@code Number --> Number}, {@code String --> Number}, {@code String --> Date}, {@code Date --> String}</li>
 * <li>基本类型数组之间的转换：{@code byte[] --> ByteBuffer}, {@code ByteBuffer --> byte[]}</li>
 * <li>日期类型的转换：{@code Date --> String}, {@code String --> Date}, {@code Date --> long}, {@code long --> Date}</li>
 * <li>系统类型之间的转换：{@code Class --> String}, {@code String --> Class}, {@code URL --> URLClassLoader}</li>
 * <li>路径类型之间的转换：{@code File --> URI}, {@code URI --> File}, {@code String --> Path}, {@code Path --> String}</li>
 * <li>枚举类型转换：{@code Enum --> Number}, {@code Number --> Enum}, {@code Enum --> String}, {@code String --> Enum}</li>
 * <li>容器类型(数组、集合、Map)类型之间的转换</li>
 * <li>支持分割转换扩展能力：{@code T --> List<R>}, {@code T --> R[]}，参见 {@link SplitTransformer}</li>
 * </ul>
 * @author guyadong
 *
 */
public class BaseTypeTransformer{
	/**
	 * 上下文对象
	 * @since 4.4.0
	 */
	protected final TransformerContext context = TransformerContext.DEFAULT;

	private final Function<Object, Object> sameTypeFun = new BaseFunction<Object, Object>(this) {
		@Override
		public Object doApply(Object input, LocalContext ltx, BaseFunction<?, ?> thisFun) {
			return input;
		}
	};
	private final Function<Void,Void> voidTypeFun = new Function<Void,Void>(){
		@Override
		public Void apply(Void input) {
			return input;
		}};
	private final Function<byte[],ByteBuffer> byteArray2ByteBufferFun = new BaseFunction<byte[],ByteBuffer>(this){
		@Override
		public ByteBuffer doApply(byte[] input, LocalContext ltx, BaseFunction<?, ?> thisFun) {
			return ByteBuffer.wrap(input);
		}};
	private final Function<ByteBuffer,byte[]> byteBuffer2ByteArrayFun = new BaseFunction<ByteBuffer,byte[]>(this){
		@Override
		public byte[] doApply(ByteBuffer input, LocalContext ltx, BaseFunction<?, ?> thisFun) {
			return getBytesInBuffer(input);
		}};
	private final Function<char[],CharBuffer> charArray2CharBufferFun = new BaseFunction<char[],CharBuffer>(this){
		@Override
		public CharBuffer doApply(char[] input, LocalContext ltx, BaseFunction<?, ?> thisFun) {
			return CharBuffer.wrap(input);
		}};
	private final Function<CharBuffer,char[]> charBuffer2CharArrayFun = new BaseFunction<CharBuffer,char[]>(this){
		@Override
		public char[] doApply(CharBuffer input, LocalContext ltx, BaseFunction<?, ?> thisFun) {
			return getCharsInBuffer(input);
		}};
	private final Function<char[],String> charArray2StringFun = new BaseFunction<char[],String>(this){
		@Override
		public String doApply(char[] input, LocalContext ltx, BaseFunction<?, ?> thisFun) {
			return new String(input);
		}};
	private final Function<String,char[]> string2CharArrayFun = new BaseFunction<String,char[]>(this){
		@Override
		public char[] doApply(String input, LocalContext ltx, BaseFunction<?, ?> thisFun) {
			return input.toCharArray();
		}};
	private final Function<URL,String> url2StringFun = new BaseFunction<URL,String>(this){
		@Override
		public String doApply(URL input, LocalContext ltx, BaseFunction<?, ?> thisFun) {
			return input.toString();
		}};
	private final Function<URI,String> uri2StringFun = new BaseFunction<URI,String>(this){
		@Override
		public String doApply(URI input, LocalContext ltx, BaseFunction<?, ?> thisFun) {
			return input.toString();
		}};
	private final Function<String,URL> string2UrlFun = new Empty2NullFunction<String,URL>(this){
		@Override
		public URL doApply(String input, LocalContext ltx, BaseFunction<?, ?> thisFun) throws MalformedURLException {
			return URI.create(input).toURL();
		}};
	private final Function<String,URI> string2UriFun = new Empty2NullFunction<String,URI>(this){
		@Override
		public URI doApply(String input, LocalContext ltx, BaseFunction<?, ?> thisFun) {
			return URI.create(input);
		}};
	private final Function<URI,URL> uri2UrlFun = new BaseFunction<URI,URL>(this){
		@Override
		public URL doApply(URI input, LocalContext ltx, BaseFunction<?, ?> thisFun) throws MalformedURLException {
			return input.toURL();
		}};
	private final Function<String,File> string2FileFun = new Empty2NullFunction<String,File>(this){
		@Override
		public File doApply(String input, LocalContext ltx, BaseFunction<?, ?> thisFun) {
			return new File(input);
		}};
	private final Function<String,Path> string2PathFun = new Empty2NullFunction<String,Path>(this){
		@Override
		public Path doApply(String input, LocalContext ltx, BaseFunction<?, ?> thisFun) {
			return Paths.get(input);
		}};
	private final Function<File,URI> file2UriFun = new BaseFunction<File,URI>(this){
		@Override
		public URI doApply(File input, LocalContext ltx, BaseFunction<?, ?> thisFun) {
			return input.toURI();
		}};
	private final Function<File,URL> file2UrlFun = Functions.compose(uri2UrlFun,file2UriFun);
	private final Function<URL,URLClassLoader> url2URLClassLoaderFun = new BaseFunction<URL,URLClassLoader>(this){
		@Override
		public URLClassLoader doApply(URL input, LocalContext ltx, BaseFunction<?, ?> thisFun) {
			return new URLClassLoader(new URL[] {input});
		}};
	protected final Function<URL[],URLClassLoader> urlArray2URLClassLoaderFun = new BaseFunction<URL[],URLClassLoader>(this, Feature.IGNORE_NULL_ELEMENT, Feature.DEFAULT, false){
		@Override
		public URLClassLoader doApply(URL[] input, LocalContext ltx, BaseFunction<?, ?> thisFun) {
			return new URLClassLoader(input);
		}};
	private final Function<String,URLClassLoader> string2URLClassLoaderFun = Functions.compose(url2URLClassLoaderFun, string2UrlFun);
	private final Function<File,URLClassLoader> file2URLClassLoaderFun = Functions.compose(url2URLClassLoaderFun, file2UrlFun);
	private final Function<URI,URLClassLoader> uri2URLClassLoaderFun = Functions.compose(url2URLClassLoaderFun, uri2UrlFun);
	private final Function<int[],List<Integer>> intArray2List = new BaseFunction<int[],List<Integer>>(this){
		@Override
		public List<Integer> doApply(int[] input, LocalContext ltx, BaseFunction<?, ?> thisFun) {
			return Ints.asList(input);
		}};
	private final Function<long[],List<Long>> longArray2List = new BaseFunction<long[],List<Long>>(this){
		@Override
		public List<Long> doApply(long[] input, LocalContext ltx, BaseFunction<?, ?> thisFun) {
			return Longs.asList(input);
		}};
	private final Function<double[],List<Double>> doubleArray2List = new BaseFunction<double[],List<Double>>(this){
		@Override
		public List<Double> doApply(double[] input, LocalContext ltx, BaseFunction<?, ?> thisFun) {
			return Doubles.asList(input);
		}};
	private final Function<float[],List<Double>> floatArray2List = new BaseFunction<float[],List<Double>>(this){
		@SuppressWarnings("unchecked")
		@Override
		public List<Double> doApply(float[] input, LocalContext ltx, BaseFunction<?, ?> thisFun) {
			return Lists.transform(Floats.asList(input),(Function<Float,Double>)number2DoubleFun);
		}};
	private final Function<short[],List<Short>> shortArray2List = new BaseFunction<short[],List<Short>>(this){
		@Override
		public List<Short> doApply(short[] input, LocalContext ltx, BaseFunction<?, ?> thisFun) {
			return Shorts.asList(input);
		}};
	private final Function<boolean[],List<Boolean>> booleanArray2List = new BaseFunction<boolean[],List<Boolean>>(this){
		@Override
		public List<Boolean> doApply(boolean[] input, LocalContext ltx, BaseFunction<?, ?> thisFun) {
			return Booleans.asList(input);
		}};
	private final Function<byte[],List<Byte>> byteArray2List = new BaseFunction<byte[],List<Byte>>(this){
		@Override
		public List<Byte> doApply(byte[] input, LocalContext ltx, BaseFunction<?, ?> thisFun) {
			return Bytes.asList(input);
		}};
	private final Function<char[],List<Character>> charArray2List = new BaseFunction<char[],List<Character>>(this){
		@Override
		public List<Character> doApply(char[] input, LocalContext ltx, BaseFunction<?, ?> thisFun) {
			return Chars.asList(input);
		}};
	private final Function<Collection<Integer>,int[]> collection2intArray = new Iterable2PrimitiveArrayFunction<Collection<Integer>,int[]>(this){
		@Override
		public int[] doApply(Collection<Integer> input, LocalContext ltx, BaseFunction<?, ?> thisFun) {
			return Ints.toArray(input);
		}};
	private final Function<Collection<Long>,long[]> collection2longArray = new Iterable2PrimitiveArrayFunction<Collection<Long>,long[]>(this){
		@Override
		public long[] doApply(Collection<Long> input, LocalContext ltx, BaseFunction<?, ?> thisFun) {
			return Longs.toArray(input);
		}};
	private final Function<Collection<Double>,double[]> collection2doubleArray = new Iterable2PrimitiveArrayFunction<Collection<Double>,double[]>(this){
		@Override
		public double[] doApply(Collection<Double> input, LocalContext ltx, BaseFunction<?, ?> thisFun) {
			return Doubles.toArray(input);
		}};
	private final Function<Collection<Double>,float[]> collection2floatArray = new Iterable2PrimitiveArrayFunction<Collection<Double>,float[]>(this){
		@Override
		public float[] doApply(Collection<Double> input, LocalContext ltx, BaseFunction<?, ?> thisFun) {
			return Floats.toArray(input);
		}};
	private final Function<Collection<Short>,short[]> collection2shortArray = new Iterable2PrimitiveArrayFunction<Collection<Short>,short[]>(this){
		@Override
		public short[] doApply(Collection<Short> input, LocalContext ltx, BaseFunction<?, ?> thisFun) {
			return Shorts.toArray(input);
		}};
	private final Function<Collection<Boolean>,boolean[]> collection2booleanArray = new Iterable2PrimitiveArrayFunction<Collection<Boolean>,boolean[]>(this){
		@Override
		public boolean[] doApply(Collection<Boolean> input, LocalContext ltx, BaseFunction<?, ?> thisFun) {
			return Booleans.toArray(input);
		}};
	private final Function<Collection<Byte>,byte[]> collection2byteArray = new Iterable2PrimitiveArrayFunction<Collection<Byte>,byte[]>(this){
		@Override
		public byte[] doApply(Collection<Byte> input, LocalContext ltx, BaseFunction<?, ?> thisFun) {
			return Bytes.toArray(input);
		}};
	private final Function<Collection<Character>,char[]> collection2charArray = new Iterable2PrimitiveArrayFunction<Collection<Character>,char[]>(this){
		@Override
		public char[] doApply(Collection<Character> input, LocalContext ltx, BaseFunction<?, ?> thisFun) {
			return Chars.toArray(input);
		}};
	private final Function<? extends Number,Byte> number2ByteFun = new BaseFunction<Number,Byte>(this){
		@Override
		public Byte doApply(Number input, LocalContext ltx, BaseFunction<?, ?> thisFun) {
			return input.byteValue();
		}};
	private final Function<? extends Number,Short> number2ShortFun = new BaseFunction<Number,Short>(this){
		@Override
		public Short doApply(Number input, LocalContext ltx, BaseFunction<?, ?> thisFun) {
			return input.shortValue();
		}};
	private final Function<? extends Number,Integer> number2IntegerFun = new BaseFunction<Number,Integer>(this){
		@Override
		public Integer doApply(Number input, LocalContext ltx, BaseFunction<?, ?> thisFun) {
			return input.intValue();
		}};
	private final Function<? extends Number,Long> number2LongFun = new BaseFunction<Number,Long>(this){
		@Override
		public Long doApply(Number input, LocalContext ltx, BaseFunction<?, ?> thisFun) {
			return input.longValue();
		}};
	private final Function<? extends Number,Float> number2FloatFun = new BaseFunction<Number,Float>(this){
		@Override
		public Float doApply(Number input, LocalContext ltx, BaseFunction<?, ?> thisFun) {
			return input.floatValue();
		}};
	private final Function<? extends Number,Double> number2DoubleFun = new BaseFunction<Number,Double>(this){
		@Override
		public Double doApply(Number input, LocalContext ltx, BaseFunction<?, ?> thisFun) {
			return input.doubleValue();
		}};
	private final Function<? extends Number,BigDecimal> number2BigDecimalFun = new BaseFunction<Number,BigDecimal>(this){
		@Override
		public BigDecimal doApply(Number input, LocalContext ltx, BaseFunction<?, ?> thisFun) {
			return BigDecimal.valueOf(input.doubleValue());
		}};
	private final Function<Number,BigInteger> number2BigIntegerFun = new BaseFunction<Number,BigInteger>(this){
		@Override
		public BigInteger doApply(Number input, LocalContext ltx, BaseFunction<?, ?> thisFun) {
			return BigInteger.valueOf(input.longValue());
		}};
	private final Function<Number,AtomicInteger> number2AtomicIntegerFun = new BaseFunction<Number,AtomicInteger>(this){
		@Override
		public AtomicInteger doApply(Number input, LocalContext ltx, BaseFunction<?, ?> thisFun) {
			return new AtomicInteger(input.intValue());
		}};
	private final Function<Number,AtomicLong> number2AtomicLongFun = new BaseFunction<Number,AtomicLong>(this){
		@Override
		public AtomicLong doApply(Number input, LocalContext ltx, BaseFunction<?, ?> thisFun) {
			return new AtomicLong(input.longValue());
		}};
	private final Function<Number,AtomicDouble> number2AtomicDoubleFun = new BaseFunction<Number,AtomicDouble>(this){
		@Override
		public AtomicDouble doApply(Number input, LocalContext ltx, BaseFunction<?, ?> thisFun) {
			return new AtomicDouble(input.doubleValue());
		}};
	private final Function<Number,Boolean> number2BooleanFun = new BaseFunction<Number,Boolean>(this){
		@Override
		public Boolean doApply(Number input, LocalContext ltx, BaseFunction<?, ?> thisFun) {
			return 0 != input.intValue();
		}};
	private final Function<Number,AtomicBoolean> number2AtomicBooleanFun = new BaseFunction<Number,AtomicBoolean>(this){
		@Override
		public AtomicBoolean doApply(Number input, LocalContext ltx, BaseFunction<?, ?> thisFun) {
			return new AtomicBoolean(0 != input.intValue());
		}};
	private final Function<String,Byte> string2ByteFun = new Empty2NullFunction<String,Byte>(this){
		@Override
		public Byte doApply(String input, LocalContext ltx, BaseFunction<?, ?> thisFun) {
			return Byte.valueOf(input);
		}};
	private final Function<String,Short> string2ShortFun = new Empty2NullFunction<String,Short>(this){
		@Override
		public Short doApply(String input, LocalContext ltx, BaseFunction<?, ?> thisFun) {
			return Short.valueOf(input);
		}};
	private final Function<String,Integer> string2IntegerFun = new Empty2NullFunction<String,Integer>(this){
		@Override
		public Integer doApply(String input, LocalContext ltx, BaseFunction<?, ?> thisFun) {
			return Integer.valueOf(input);
		}};
	private final Function<String,Long> string2LongFun = new Empty2NullFunction<String,Long>(this){
		@Override
		public Long doApply(String input, LocalContext ltx, BaseFunction<?, ?> thisFun) {
			return Long.valueOf(input);
		}};
	private final Function<String,Float> string2FloatFun = new Empty2NullFunction<String,Float>(this){
		@Override
		public Float doApply(String input, LocalContext ltx, BaseFunction<?, ?> thisFun) {
			return Float.valueOf(input);
		}};
	private final Function<String,Double> string2DoubleFun = new Empty2NullFunction<String,Double>(this){
		@Override
		public Double doApply(String input, LocalContext ltx, BaseFunction<?, ?> thisFun) {
			return Double.valueOf(input);
		}};
	private final Function<String,BigDecimal> string2BigDecimalFun = new Empty2NullFunction<String,BigDecimal>(this){
		@Override
		public BigDecimal doApply(String input, LocalContext ltx, BaseFunction<?, ?> thisFun) {
			return new BigDecimal(input);
		}};
	private final Function<String,BigInteger> string2BigIntegerFun = new Empty2NullFunction<String,BigInteger>(this){
		@Override
		public BigInteger doApply(String input, LocalContext ltx, BaseFunction<?, ?> thisFun) {
			return new BigInteger(input);
		}};
	private final Function<String,Boolean> string2BooleanFun = new Empty2NullFunction<String,Boolean>(this){
		@Override
		public Boolean doApply(String input, LocalContext ltx, BaseFunction<?, ?> thisFun) {
			return Boolean.valueOf(input);
		}};
	private final Function<Boolean,Byte> boolean2ByteFun = new BooleanToNumber<Byte>(this) {};
	private final Function<Boolean,Short> boolean2ShortFun = new BooleanToNumber<Short>(this) {};
	private final Function<Boolean,Integer> boolean2IntegerFun = new BooleanToNumber<Integer>(this) {};
	private final Function<Boolean,Long> boolean2LongFun = new BooleanToNumber<Long>(this) {};
	private final Function<Boolean,Float> boolean2FloatFun = new BooleanToNumber<Float>(this) {};
	private final Function<Boolean,Double> boolean2DoubleFun = new BooleanToNumber<Double>(this) {};
	private final Function<Date,Long> date2LongFun = new BaseFunction<Date,Long>(this){
		@Override
		public Long doApply(Date input, LocalContext ltx, BaseFunction<?, ?> thisFun) {
			return input.getTime();
		}};
	private final Function<Date,String> date2StringFun = new BaseFunction<Date,String>(this){
		@Override
		public String doApply(Date input, LocalContext ltx, BaseFunction<?, ?> thisFun) {
			return  formatDate(input,TIMESTAMP_FORMATTER_STR);
		}};
	private final Function<String,Date> string2DateFun = new Empty2NullFunction<String,Date>(this){
		@Override
		public Date doApply(String input, LocalContext ltx, BaseFunction<?, ?> thisFun) {
			return  getDateFromString(input);
		}};
	private final Function<String,java.sql.Date> string2SqlDateFun = new Empty2NullFunction<String,java.sql.Date>(this){
		@Override
		public java.sql.Date doApply(String input, LocalContext ltx, BaseFunction<?, ?> thisFun) {
			return new java.sql.Date(getDateFromString(input).getTime());
		}};
	private final Function<String,java.sql.Time> string2SqlTimeFun = new Empty2NullFunction<String,java.sql.Time>(this){
		@Override
		public java.sql.Time doApply(String input, LocalContext ltx, BaseFunction<?, ?> thisFun) {
			return new java.sql.Time(getDateFromString(input).getTime());
		}};
	private final Function<String,Timestamp> string2TimestampFun = new Empty2NullFunction<String,Timestamp>(this){
		@Override
		public Timestamp doApply(String input, LocalContext ltx, BaseFunction<?, ?> thisFun) {
			return new Timestamp(getDateFromString(input).getTime());
		}};
	private final Function<Number,Date> number2DateFun = new BaseFunction<Number,Date>(this){
		@Override
		public Date doApply(Number input, LocalContext ltx, BaseFunction<?, ?> thisFun) {
			return  new Date(input.longValue());
		}};
	private final Function<Number,java.sql.Date> number2SqlDateFun = new BaseFunction<Number,java.sql.Date>(this){
		@Override
		public java.sql.Date doApply(Number input, LocalContext ltx, BaseFunction<?, ?> thisFun) {
			return  new java.sql.Date(input.longValue());
		}};
	private final Function<Number,java.sql.Time> number2SqlTimeFun = new BaseFunction<Number,java.sql.Time>(this){
		@Override
		public java.sql.Time doApply(Number input, LocalContext ltx, BaseFunction<?, ?> thisFun) {
			return  new java.sql.Time(input.longValue());
		}};
	private final Function<Number,Timestamp> number2TimestampFun = new BaseFunction<Number,Timestamp>(this){
		@Override
		public Timestamp doApply(Number input, LocalContext ltx, BaseFunction<?, ?> thisFun) {
			return  new Timestamp(input.longValue());
		}};
	private final Function<Date,? extends Date> date2SubFun = new Date2SubTransformer<Date>(this);
	private final Function<UUID, String> uuidToStringFun = new BaseFunction<UUID, String>(this) {
		@Override
		public String doApply(UUID input, LocalContext ltx, BaseFunction<?, ?> thisFun) {
			return input.toString();
		}
	};
	private final Function<UUID, byte[]> uuidToBytesFun = new BaseFunction<UUID, byte[]>(this) {
		@Override
		public byte[] doApply(UUID input, LocalContext ltx, BaseFunction<?, ?> thisFun) {
			ByteBuffer bb = ByteBuffer.wrap(new byte[16]);
			bb.putLong(input.getMostSignificantBits());
			bb.putLong(input.getLeastSignificantBits());
			return bb.array();
		}
	};
	private final Function<String, UUID> stringToUuidFun = new Empty2NullFunction<String, UUID>(this) {
		@Override
		public UUID doApply(String input, LocalContext ltx, BaseFunction<?, ?> thisFun) throws IllegalArgumentException {
			return UUID.fromString(input);
		}
	};
	private final Function<byte[], UUID> bytesToUuidFun = new Empty2NullFunction<byte[], UUID>(this) {
		@Override
		public UUID doApply(byte[] input, LocalContext ltx, BaseFunction<?, ?> thisFun) throws IllegalArgumentException {
			if (input.length != 16) {
				throw new IllegalArgumentException("Byte array must be 16 bytes");
			}
			ByteBuffer bb = ByteBuffer.wrap(input);
			return new UUID(bb.getLong(), bb.getLong());
		}
	};
	private final Function<Object,String> object2StringFun = new BaseFunction<Object,String>(this){
		@Override
		public String doApply(Object input, LocalContext ltx, BaseFunction<?, ?> thisFun) {
			return input.toString();
		}};
	private final Function<Enum<?>,Integer> enum2IntegerFun = new BaseFunction<Enum<?>,Integer>(this){
		@Override
		public Integer doApply(Enum<?> input, LocalContext ltx, BaseFunction<?, ?> thisFun) {
			return input.ordinal();
		}};
	private final Function<String,Class<?>> className2ClassFun = new ClassName2ClassFunction(this);
	private final Function<Class<?>,String> class2ClassNameFun = new BaseFunction<Class<?>,String>(this){
		@Override
		public String doApply(Class<?> input, LocalContext ltx, BaseFunction<?, ?> thisFun) {
			return input.getName();
		}};
	protected final Table<Type,Type,Function<?,?>> transTable = HashBasedTable.create();
	/** 
	 * {@link #transTable} 读写锁
	 * @since 4.4.0
	 */
	protected final ReentrantReadWriteLock transTableLock = new ReentrantReadWriteLock();

	public BaseTypeTransformer() {
		transTable.put(byte[].class,ByteBuffer.class,byteArray2ByteBufferFun);
		transTable.put(ByteBuffer.class,byte[].class,byteBuffer2ByteArrayFun);
		transTable.put(char[].class,CharBuffer.class,charArray2CharBufferFun);
		transTable.put(CharBuffer.class,char[].class,charBuffer2CharArrayFun);
		transTable.put(char[].class,String.class,charArray2StringFun);
		transTable.put(String.class,char[].class,string2CharArrayFun);
		transTable.put(URL.class,String.class,url2StringFun);
		transTable.put(URI.class,String.class,uri2StringFun);
		transTable.put(String.class,URL.class,string2UrlFun);
		transTable.put(String.class,URI.class,string2UriFun);
		transTable.put(URI.class,URL.class,uri2UrlFun);
		transTable.put(String.class,File.class,string2FileFun);
		transTable.put(String.class,Path.class,string2PathFun);
		transTable.put(File.class,URI.class,file2UriFun);
		transTable.put(File.class,URL.class,file2UrlFun);
		transTable.put(URL.class,URLClassLoader.class,url2URLClassLoaderFun);
		transTable.put(URL[].class,URLClassLoader.class,urlArray2URLClassLoaderFun);
		transTable.put(String.class,URLClassLoader.class,string2URLClassLoaderFun);
		transTable.put(File.class,URLClassLoader.class,file2URLClassLoaderFun);
		transTable.put(URI.class,URLClassLoader.class,uri2URLClassLoaderFun);

		transTable.put(Void.class, void.class, voidTypeFun);
		
		transTable.put(Number.class,Byte.class,number2ByteFun);
		transTable.put(Number.class,Short.class,number2ShortFun);
		transTable.put(Number.class,Integer.class,number2IntegerFun);
		transTable.put(Number.class,Long.class,number2LongFun);
		transTable.put(Number.class,Float.class,number2FloatFun);
		transTable.put(Number.class,Double.class,number2DoubleFun);
		transTable.put(Number.class,BigDecimal.class,number2BigDecimalFun);
		transTable.put(Number.class,BigInteger.class,number2BigIntegerFun);
		transTable.put(Number.class,AtomicInteger.class,number2AtomicIntegerFun);
		transTable.put(Number.class,AtomicLong.class,number2AtomicLongFun);
		transTable.put(Number.class,AtomicDouble.class,number2AtomicDoubleFun);
		
		transTable.put(Number.class,Boolean.class,number2BooleanFun);
		transTable.put(Number.class,AtomicBoolean.class,number2AtomicBooleanFun);
		
		transTable.put(String.class,Byte.class,string2ByteFun);
		transTable.put(String.class,Short.class,string2ShortFun);
		transTable.put(String.class,Integer.class,string2IntegerFun);
		transTable.put(String.class,Long.class,string2LongFun);
		transTable.put(String.class,Float.class,string2FloatFun);
		transTable.put(String.class,Double.class,string2DoubleFun);
		transTable.put(String.class,BigDecimal.class,string2BigDecimalFun);
		transTable.put(String.class,BigInteger.class,string2BigIntegerFun);
		transTable.put(String.class,Boolean.class,string2BooleanFun);
		
		transTable.put(Boolean.class,Byte.class,boolean2ByteFun);
		transTable.put(Boolean.class,Short.class,boolean2ShortFun);
		transTable.put(Boolean.class,Integer.class,boolean2IntegerFun);
		transTable.put(Boolean.class,Long.class,boolean2LongFun);
		transTable.put(Boolean.class,Float.class,boolean2FloatFun);
		transTable.put(Boolean.class,Double.class,boolean2DoubleFun);

		transTable.put(Date.class,Long.class,date2LongFun);
		
		transTable.put(Date.class,String.class,date2StringFun);


		transTable.put(String.class,Date.class,string2DateFun);
		transTable.put(String.class,java.sql.Date.class,string2SqlDateFun);
		transTable.put(String.class,java.sql.Time.class,string2SqlTimeFun);
		transTable.put(String.class,Timestamp.class,string2TimestampFun);
		transTable.put(Number.class,Date.class,number2DateFun);
		transTable.put(Number.class,java.sql.Date.class,number2SqlDateFun);
		transTable.put(Number.class,java.sql.Time.class,number2SqlTimeFun);
		transTable.put(Number.class,Timestamp.class,number2TimestampFun);
		/** 添加Date --> 子类 (? extend Date) 转换器 */
		transTable.put(Date.class, ((BaseFunction<?, ?>) date2SubFun).outputType.getType(), date2SubFun);

	    /** 添加UUID转换器 */
	    transTable.put(UUID.class, String.class, uuidToStringFun);
	    transTable.put(String.class, UUID.class, stringToUuidFun);
	    transTable.put(UUID.class, byte[].class, uuidToBytesFun);
	    transTable.put(byte[].class, UUID.class, bytesToUuidFun);
	    
		transTable.put(String.class,Class.class,className2ClassFun);
		transTable.put(Class.class,String.class,class2ClassNameFun);

		/*** 泛型转换表 */
		transTable.put(int[].class, of(List.class, Integer.class), intArray2List);
		transTable.put(long[].class, of(List.class, Long.class), longArray2List);
		transTable.put(double[].class, of(List.class, Double.class), doubleArray2List);
		transTable.put(float[].class, of(List.class, Float.class), floatArray2List);
		transTable.put(short[].class, of(List.class, Short.class), shortArray2List);
		transTable.put(boolean[].class, of(List.class, Boolean.class), booleanArray2List);
		transTable.put(byte[].class, of(List.class, Byte.class), byteArray2List);
		transTable.put(char[].class, of(List.class, Character.class), charArray2List);
		transTable.put(of(Collection.class, Integer.class), int[].class, collection2intArray);
		transTable.put(of(Collection.class, Long.class), long[].class, collection2longArray);
		transTable.put(of(Collection.class, Double.class), double[].class, collection2doubleArray);
		transTable.put(of(Collection.class, Float.class), float[].class, collection2floatArray);
		transTable.put(of(Collection.class, Short.class), short[].class, collection2shortArray);
		transTable.put(of(Collection.class, Boolean.class), boolean[].class, collection2booleanArray);
		transTable.put(of(Collection.class, Byte.class), byte[].class, collection2byteArray);
		transTable.put(of(Collection.class, Character.class), char[].class, collection2charArray);
	}
	/**
	 * 定义 {@code left -> right}的转换器
	 * @param <L>
	 * @param <R>
	 * @param left
	 * @param right
	 * @param trans
	 * @param overwrite 是否覆盖已存在的转换器
	 * @return always return this object
	 * @since 4.4.0
	 */
	protected <L,R>BaseTypeTransformer setTransformer(Type left, Type right, Function<L, R> trans,boolean overwrite){
		checkArgument(null != left && null != right && null != trans,"left, right, trans must not be null");
		transTableLock.writeLock().lock();
		try{
			if(overwrite || !transTable.contains(left, right)){
				transTable.put(left,right,trans);
			}
		}finally{
			transTableLock.writeLock().unlock();
		}
		return this;
	}
	/**
	 * 设置{@code left -> right}的转换器，参数不可为{@code null}
	 * @param left
	 * @param right
	 * @param trans 转换器对象
	 * @return 当前对象
	 */
	public <L,R>BaseTypeTransformer setTransformer(Class<L> left, Class<R> right, Function<L, R> trans){
		return setTransformer((Type) left, (Type) right, trans, true);
	}
	public <L, R> BaseTypeTransformer setTransformer(Type left, Type right, Function<L, R> trans) {
		return setTransformer(left, right, trans, true);
	}

	private Function<?, ?> getTransformerFromTable(TypeToken<?> left, TypeToken<?> right) {
		transTableLock.readLock().lock();
		try {
			return transTable.get(left.getType(), right.getType());
		} finally {
			transTableLock.readLock().unlock();
		}
	}

	private Function<?,?> getTransformer0(Type left, Type right, boolean subMatched) {
		return getTransformer0(TypeToken.of(left),TypeToken.of(right), subMatched);
	}
	/**
	 * 获取{@code left -> right}的转换器，参数不可为{@code null}
	 * 如果 {@link #transTable}表中没有找到匹配的转换器，且{@code subMatched}为{@code true}，则会尝试以类型匹配规则查找匹配的转换器<br>
	 * 规则：
	 * 如果left是cell.getColumnKey()的超类，right是cell.getRowKey()的子类， 则认为匹配成功<br>
	 * 如： {@code List<Integer>} -> {@code Collection<? extends Number>}，则会匹配 {@code Iterable<? extends Number> -> Set<Integer>} <br>
	 * @param left
	 * @param right
	 * @param subMatched 如果没有找到匹配的转换器，是否以类型匹配规则查找匹配的转换器
	 * @return 转换器对象
	 * @see #searchMatchedTransformer(TypeToken, TypeToken)
	 */
	protected Function<?, ?> getTransformer0(TypeToken<?> left, TypeToken<?> right, boolean subMatched) {
		Function<?, ?> transformer = getTransformerFromTable(left, right);
		if (null == transformer && subMatched) {
			if ((transformer = searchMatchedTransformer(left,right)) != null) {
				setTransformer(left.getType(), right.getType(), transformer, false);
			}
		}
		return transformer;
	}
	/**
	 * 尝试以类型匹配规则查找匹配的转换器，如果没有找到匹配的转换器，则返回{@code null}
	 * @param left
	 * @param right
	 * @see #computeMatchScore(TypeToken, TypeToken, TypeToken, TypeToken)
	 */
	private Function<?, ?> searchMatchedTransformer(final TypeToken<?> left, final TypeToken<?> right) {
		transTableLock.readLock().lock();
		try{
			Function<?, ?> transformer = null;
			FluentIterable<Entry<Integer, Function<?, ?>>> scoreEntries = FluentIterable
					.from(transTable.cellSet())
					.transform(new Function<Cell<Type, Type, Function<?, ?>>, Map.Entry<Integer, Function<?, ?>>>() {
						
						@Override
						public Map.Entry<Integer, Function<?, ?>> apply(Cell<Type, Type, Function<?, ?>> input) {
							int score = computeMatchScore(left, right, TypeToken.of(input.getRowKey()),
									TypeToken.of(input.getColumnKey()));
//							if(score > 0){
//								System.out.printf("%s -> %s match %s -> %s score:%d\n",input.getRowKey(), input.getColumnKey(), left,right,score);
//							}
							return new SimpleImmutableEntry<Integer, Function<?, ?>>(score, input.getValue());
						}
					}).filter(
							/** 过滤分值不为0的转换器 */
							new Predicate<Map.Entry<Integer, Function<?, ?>>>() {
								
								@Override
								public boolean apply(Entry<Integer, Function<?, ?>> input) {
									return input.getKey() > 0;
								}
							});
			if (!scoreEntries.isEmpty()) {
				ImmutableListMultimap<Integer, Function<?, ?>> matchedFunctions = ImmutableListMultimap
						.copyOf(scoreEntries);
				if (matchedFunctions.size() == 1) {
					/** 只有一个匹配的转换器则直接返回 */
					transformer = matchedFunctions.values().iterator().next();
				} else {
					/** 多个转换器匹配到同一个类型，选择分值最高的转换器 */
					int max = Ints.max(Ints.toArray(matchedFunctions.keys()));
					transformer = matchedFunctions.get(max).iterator().next();
				}
			}
			return transformer;
		} finally {
			transTableLock.readLock().unlock();
		}
	}

	/**
	 * 如果 {@code result}的输出类型与 {@code right}不相同，则返回一个输出类型为 {@code right}的新
	 * {@link BaseFunction}对象作为该类型转换器<br>
	 * 当右值类型为基本类型时，匹配的转换器所支持的输出类型(即 {@link BaseFunction#outputType()} )可能是对应的包装类型， 如
	 * {@code int -> Integer}，则需要将转换器的输出类型修改为原始类型，否则会导致类型转换失败。
	 * 
	 * @see BaseFunction#wrap(BaseTypeTransformer, TypeToken, TypeToken, Function)
	 */
	@SuppressWarnings({ "unchecked", "rawtypes" })
	private Function<?, ?> formatTransformer(Function<?, ?> result, final TypeToken<?> left, final TypeToken<?> right) {
		Function replaced = BaseFunction.wrap(this, left, right, result);
		if (replaced != result) {
			setTransformer(left.getType(), right.getType(), replaced, false);
			result = replaced;
		}
		return result;
	}
	/**
	 * 返回{@code left->right}的类型转换器，参数不可为{@code null}
	 * @param left
	 * @param right
	 * @return transformer Function 
	 * @since 4.4.0
	 */
	@SuppressWarnings({ "rawtypes", "unchecked" })
	@AoWeakCacheable(expireAfterAccess = 30, expireAfterAccessTimeUnit = TimeUnit.SECONDS)
	protected Function<?, ?> getTransformer(final TypeToken<?> left, final TypeToken<?> right) {
		checkArgument(null != left && null != right, "left, right must not be null");
		Function result = getTransformer0(left, right, true);
		if (null == result) {
			if (isNoPrimitiveAssignable(left, right)) {
				// 相同类型转换
				return formatTransformer(this.sameTypeFun, left, right);
			}
			/** 如果没有从 {@link #transTable}表中找到匹配的转换器，则尝试根据类型创建转换器 */
			Class<?> leftClass = left.getRawType();
			Class<?> rightClass = right.getRawType();
			if (Enum.class.isAssignableFrom(leftClass) && Enum.class.isAssignableFrom(rightClass)) {
				// 添加枚举类型转换
				result = new EnumTransformer((Class<? extends Enum<?>>) leftClass,
						(Class<? extends Enum<?>>) rightClass);
			} else if (Enum.class.isAssignableFrom(leftClass) && Integer.class.isAssignableFrom(rightClass)) {
				/** 枚举类型转换为int */
				result = enum2IntegerFun;
			} else if (Enum.class.isAssignableFrom(leftClass) && Number.class.isAssignableFrom(Primitives.wrap(rightClass))) {
				/** 枚举类型转换为Number */
				result = compose((Function<Integer, ?>)getTransformer0(TypeToken.of(Integer.class), right, true), enum2IntegerFun);
			} else if (Number.class.isAssignableFrom(Primitives.wrap(leftClass)) && Enum.class.isAssignableFrom(rightClass)) {
				/** Number类型转换为枚举 */
				result = new Number2Enum(this, rightClass) {
				};
			} else if (String.class.equals(leftClass) && Enum.class.isAssignableFrom(rightClass)) {
				/** String类型转换为枚举 */
				result = new String2Enum(this, rightClass);
			} else if (String.class.equals(rightClass)) {
				/** toString */
				result = object2StringFun;
			} else if (Map.Entry.class.equals(leftClass) && Map.Entry.class.equals(rightClass)) {
				/**
				 * Map.Entry类型转换, 如Map<String,Integer> -> Map<String,String> 参见
				 * BaseContainerTransformer#getIterableLeft(Object)方法 和
				 * BaseContainerTransformer#build(Iterable)方法中对Map.Entry的处理
				 */
				result = new GenericEntryTransformer(this, (ParameterizedType) left.getType(), (ParameterizedType) right.getType());
			} else if (isContainerType(right)) {
				if (!isContainerType(left) ) {
					if (getTransformer0(left, TypeToken.of(of(Iterable.class, left.getType())), true) != null) {
						/** 如果left不是容器类型，但是right是容器类型，且存在left -> Iterable<left>的转换器，则使用分割器类型转换 **/
						result = new SplitTransformer(this, left, right);
					} else if (Object.class == left.getType()) {
						/** 未知类型--> right 转换 */
						result = new DynamicTransformer(this, right);
					}else if (Object.class == leftClass) {
						/** TypeVariable --> right 转换, left换成Object.class执行递归调用 */
						return getTransformer(TypeToken.of(Object.class), right);
					}else {
						throw new IllegalArgumentException(String.format(
								"left is not a container type %s, right is a container type %s, but no transformer found for %s -> Iterable<%s>",
								left, right, left, left));
					}
				} else {
					/** 容器类型转换 */
					result = new ContainerTransformer(this, left, right) ;
				}
			} else if(isContainerType(left)){
				/** 容器类型->非容器类型转换 */
				TypeToken<?> elementType = elementTypeOf(left, true);
				if(left.isArray()){
					/** 查找 left -> Iterable<elementType> -> right 的转换器 */
					result = getTransformer(left,TypeToken.of(of(Iterable.class, elementType.getType())), right);
				}else{
					/** 查找 left -> elementType[] -> right 的转换器 */
					result = getTransformer(left,arrayTypeOf(elementType), right);
				}
			} else if (Object.class == left.getType()) {
				/** 未知类型--> right 转换 */
				result = new DynamicTransformer(this, right);
			} else if (Object.class == leftClass) {
				/** TypeVariable --> right 转换, left换成Object.class执行递归调用 */
				return getTransformer(TypeToken.of(Object.class), right);
			}
			if (null != result) {
				setTransformer(left.getType(), right.getType(), result);
			}
		}else{
			result = formatTransformer(result, left, right);
		}
		return result;
	}
	@SuppressWarnings("unchecked")
	protected <L, R> Function<L, R> getTransformerChecked(TypeToken<?> left, TypeToken<?> right) {
		return checkNotNull((Function<L, R>)getTransformer(left, right), "not found transformer for %s to %s", left, right);
	}
	/**
	 * 返回{@code left->right}的类型转换器<br>
	 * 如果指定了中间类型({@code middle}不为{@code null})，则会尝试返回以{@code middle}作为中间类型的转换器, 即
	 * {@code left->middle->right}的间接转换器
	 * 
	 * @param left 原类型
	 * @param middle 中间类型，为{@code null}忽略
	 * @param right 目标类型
	 * @return transformer Function
	 * @since 4.4.0
	 */
	@SuppressWarnings({ "unchecked", "rawtypes" })
	protected Function<?, ?> getTransformer(TypeToken<?> left, TypeToken<?> middle, TypeToken<?> right) {
		checkArgument(null != left && null != right, "left, right must not be null");
		if (null == middle 	|| isAssignable(left , middle) || isAssignable(middle, right)) {
			return getTransformer(left, right);
		}
		final Function g = getTransformer(middle, right);
		final Function f = getTransformer(left, middle);
//		return null == g || null == f ? null : Functions.compose(g, f);
		/**
		 * 将 {@code g} 和 {@code f} 组合成 {@code left->right}的转换器并封装为
		 * {@link BaseFunction}对象
		 */
		return null == g || null == f ? null : new BaseFunction(this, left, right) {
			@Override
			public Object doApply(Object input, LocalContext ltx, BaseFunction thisFun) {
				return g.apply(f.apply(input));
			}
		};

	}
	/**
	 * @see #getTransformer(TypeToken, TypeToken, TypeToken)
	 * @since 4.4.0
	 */
	protected Function<?, ?> getTransformerChecked(TypeToken<?> left, TypeToken<?> middle, TypeToken<?> right) {
		return checkNotNull(getTransformer(left, middle, right), "not found transformer for %s -> %s -> %s", left,
				middle, right);
	}
	/**
	 * 返回{@code left TO right}指定的转换器，参数不可为{@code null}
	 * @param left
	 * @param right
	 * @return transformer Function 
	 */
	public <L,R>Function<L,R> getTransformer(Class<L>left,Class<R>right){
		return getTransformer((Type)left,(Type)right);
	}
	public <L,R>Function<L,R> getTransformerChecked(Class<L>left,Class<R>right){
		return checkNotNull(getTransformer(left,right),"not found transformer for %s to %s",left,right);
	}
	/**
	 * 返回{@code left->right}的类型转换器，参数不可为{@code null}
	 * @param left
	 * @param right
	 * @return transformer Function 
	 * @since 4.4.0
	 */
	@SuppressWarnings({ "unchecked" })
	public <L, R> Function<L, R> getTransformer(final Type left, final Type right) {
		return (Function<L, R>) getTransformer(TypeToken.of(left), TypeToken.of(right));
	}
	@SuppressWarnings("unchecked")
	public <L, R> Function<L, R> getTransformerChecked(Type left, Type right) {
		return checkNotNull((Function<L,R>)getTransformer(left,right),"not found transformer for %s to %s",left,right);
	}
	/**
	 * @see #getTransformer(TypeToken, TypeToken, TypeToken)
	 * @since 4.4.0
	 */
	protected Function<?, ?> getTransformerChecked(Type left, Type middle, Type right) {
		return checkNotNull(getTransformer(null == left ? null : TypeToken.of(left),
				null == middle ? null : TypeToken.of(middle), 
				null == right ? null : TypeToken.of(right)),
				"not found transformer for %s -> %s -> %s", left, middle, right);
	}
	/**
	 * 判断是否能执行{@code left->right}的类型转换<br>
	 * 输入参数为{@code null}时，返回{@code false}
	 * @param left
	 * @param right
	 * @since 4.4.0
	 */
	public boolean canTransform(Type left, Type right) {
		return null != left && null != right && null != getTransformer(left, right);
	}
	/**
	 * 对{@code value}完成{@code left->right}的类型转换<br>
	 * 如果指定了中间类型，则支持 {@code left->middle->right}的间接转换 
	 * @param value
	 * @param left   {@code value}的原类型
	 * @param middle 中间类型,为{@code null}忽略
	 * @param right  目标类型
	 * @param features 转换器特性
	 * @return R instance
	 * @since 4.4.0
	 * @see #getTransformer(Type, Type, Type)
	 */
	@SuppressWarnings("unchecked")
	private <L, R> R to(L value, TypeToken<?> left, TypeToken<?> middle, TypeToken<?> right, ContextProvider... features) {
		checkArgument(null != left, "left is null");
		checkArgument(null != right, "right is null");
		if (null == value) {
			/**
			 * 如果没有定义额外的转换器特性，比如 {@link Feature#NUL_TO_EMPTY}，则直接返回 {@code null}
			 */
			if(null == features || features.length == 0) {
				checkNotNullForPrimitive(value, right);
				return null;
			}
		}
		if ( value != null && (null == features || features.length == 0) && isAssignable(left, right)) {
			return (R) value;
		}
		Function<L, R> transformer = (Function<L, R>) this.getTransformerChecked(left, middle, right);
		/** 如果定义了额外的转换器特性，尝试应用特性 */
		if(null != features && features.length > 0){
			ContextProvider context = ContextContainer.merge(this.context, features);
			if (context != this.context) {
				checkArgument(transformer instanceof BaseFunction, "transformer is not a BaseFunction, cannot apply context");
				return ((BaseFunction<L, R>) transformer).apply(value, context.getContext());
			}
		}
		return transformer.apply(value);
	}
	/**
	 * 对{@code value}完成{@code left->right}的类型转换
	 * 
	 * @param value
	 * @param left     {@code value}的原类型
	 * @param middle 中间类型
	 * @param right    目标类型
	 * @param features 转换器特性
	 * @return R instance
	 * @since 4.4.0
	 */
	@SuppressWarnings("unchecked")
	public <L, R> R to(L value, Type left, Type middle, Type right, ContextProvider... features) {
		checkArgument(null != left, "left is null");
		checkArgument(null != right, "right is null");
		if (null == value) {
			/**
			 * 如果没有定义额外的转换器特性，比如 {@link Feature#NUL_TO_EMPTY}，则直接返回 {@code null}
			 */
			if(null == features || features.length == 0) {
				checkNotNullForPrimitive(value, right);
				return null;
			}
		}
		if ( value != null && (null == features || features.length == 0) && isAssignable(left, right)) {
			return (R) value;
		}
		Function<L, R> transformer = (Function<L, R>) this.getTransformerChecked(left, middle, right);
		/** 如果定义了额外的转换器特性，尝试应用特性 */
		if(null != features && features.length > 0){
			ContextProvider context = ContextContainer.merge(this.context, features);
			if (context != this.context) {
				checkArgument(transformer instanceof BaseFunction, "transformer is not a BaseFunction, cannot apply context");
				return ((BaseFunction<L, R>) transformer).apply(value, context.getContext());
			}
		}
		return transformer.apply(value);
	}
	/**
	 * 对{@code value}完成{@code left->right}的类型转换
	 * 
	 * @param value
	 * @param left     {@code value}的原类型
	 * @param right    目标类型
	 * @param features 转换器特性
	 * @return R instance
	 */
	public <L, R> R to(L value, Type left, Type right, ContextProvider... features) {
		return to(value, left, null, right, features);
	}
	/**
	 * 对{@code value}完成{@code left->right}的类型转换
	 * @param value
	 * @param left {@code value}的原类型
	 * @param right 目标类型
	 * @param features 转换器特性
	 * @return R instance
	 */
	public <L,R> R to (L value,Class<L>left,Class<R> right, ContextProvider... features){
		return to(value,(Type)left, (Type)right, features);
	}

	/**
	 * 对{@code value}完成{@code left->right}的类型转换<br>
	 * @param value
	 * @param left   {@code value}的原类型
	 * @param right  目标类型
	 * @param features 转换器特性
	 * @return R instance
	 * @since 4.4.0
	 * @see #to(Object, TypeToken, TypeToken, TypeToken, ContextProvider...)
	 */
	public <L, R> R to(L value, TypeToken<L> left, TypeToken<R> right, ContextProvider... features) {
		return to(value, left, null, right, features);
	}

	/**
	 * 对{@code value}完成到{@code right}指定类型的转换，自动推断左值类型<br>
	 * 
	 * @param value    输入值，其运行时类型作为左值类型
	 * @param right    目标类型
	 * @param features 转换器特性
	 * @return R instance
	 * @since 4.4.0
	 */
	public <L, R> R to(L value, TypeToken<R> right, ContextProvider... features) {
		TypeToken<?> leftType = (value != null) ? TypeToken.of(value.getClass()) : TypeToken.of(Object.class);
		return to(value, leftType, null, right, features);
	}

	/**
	 * 对{@code value}完成到{@code right}指定类型的转换，自动推断左值类型<br>
	 * 
	 * @param value    输入值，其运行时类型作为左值类型
	 * @param right    目标类型
	 * @param features 转换器特性
	 * @return R instance
	 * @since 4.4.0
	 */
	@SuppressWarnings("unchecked")
	public <L, R> R to(L value, Type right, ContextProvider... features) {
		return (R) to(value, TypeToken.of(right), features);
	}

	/**
	 * 对{@code value}完成到{@code right}指定类型的转换，自动推断左值类型<br>
	 * 
	 * @param value    输入值，其运行时类型作为左值类型
	 * @param right    目标类型
	 * @param features 转换器特性
	 * @return R instance
	 * @since 4.4.0
	 */
	public <L, R> R to(L value, Class<R> right, ContextProvider... features) {
		return to(value, TypeToken.of(right), features);
	}
	/**
	 * 将 List 中的元素转换为{@code right}指定的类型
	 * @param input
	 * @param left 列表元素原类型
	 * @param right 列表元素目标类型
	 * @return R List
	 * @deprecated replace by {@link #to(Object, Type, Type, ContextProvider...)}
	 */
	public <L,R>List<R> to(List<L> input,Class<L> left, Class<R> right){
		return null == input 
				? null 
				: Lists.transform(input, this.getTransformerChecked(left, right));
	}
	/**
	 * 将 Set 中的元素转换为{@code right}指定的类型
	 * @param input
	 * @param left 集合元素原类型
	 * @param right 集合元素目标类型
	 * @return R set
	 * @deprecated replace by {@link #to(Object, Type, Type, ContextProvider...)}
	 */
	public <L,R> Set<R> to(Set<L> input,Class<L> left, Class<R> right){
		return null == input 
				? null 
				: Sets.newHashSet(Iterables.transform(input, this.getTransformerChecked(left, right)));
	}
	/**
	 * 将 数组 中的元素转换为{@code right}指定的类型
	 * @param input
	 * @param left 数组元素原类型
	 * @param right 数组元素目标类型
	 * @return R list
	 * @deprecated replace by {@link #to(Object, Type, Type, ContextProvider...)}
	 */
	public <L,R> List<R> to(L[] input,Class<L> left,Class<R> right){
		if(null == input){
			return null;
		}
		return to(Arrays.asList(input),left,right);
	}
	/**
	 * 将 int[] 转换为列表
	 * @param input
	 * @param left 
	 * @param right 
	 * @return Integer list
	 * @deprecated replace by {@link #to(Object, Type, Type, ContextProvider...)}
	 */
	public List<Integer> to(int[] input,Class<Integer>left,Class<Integer> right){
		return intArray2List.apply(input);
	}
	/**
	 * 将 long[] 转换为列表
	 * @param input
	 * @param left 
	 * @param right 
	 * @return Long list
	 * @deprecated replace by {@link #to(Object, Type, Type, ContextProvider...)}
	 */
	public List<Long> to(long[] input,Class<Long>left,Class<Long> right){
		return longArray2List.apply(input);
	}
	/**
	 * 将 double[] 转换为列表
	 * @param input
	 * @param left 
	 * @param right 
	 * @return Double list
	 * @deprecated replace by {@link #to(Object, Type, Type, ContextProvider...)}
	 */
	public List<Double> to(double[] input,Class<Double>left,Class<Double> right){
		return doubleArray2List.apply(input);
	}
	/**
	 * 将 float[] 转换为Double列表
	 * @param input
	 * @param left 
	 * @param right 
	 * @return Double list
	 * @deprecated replace by {@link #to(Object, Type, Type, ContextProvider...)}
	 */
	public List<Double> to(float[] input,Class<Float>left,Class<Double> right){
		return floatArray2List.apply(input);
	}
	/**
	 * 将 short[] 转换为列表
	 * @param input
	 * @param left 
	 * @param right 
	 * @return Short list
	 * @deprecated replace by {@link #to(Object, Type, Type, ContextProvider...)}
	 */
	public List<Short> to(short[] input,Class<Short>left,Class<Short> right){
		return shortArray2List.apply(input);
	}
	/**
	 * 将 boolean[] 转换为列表
	 * @param input
	 * @param left 
	 * @param right 
	 * @return Boolean list
	 * @deprecated replace by {@link #to(Object, Type, Type, ContextProvider...)}
	 */
	public List<Boolean> to(boolean[] input,Class<Boolean>left,Class<Boolean> right){
		return booleanArray2List.apply(input);
	}
	/**
	 * 将 列表 转换为数组
	 * @param input
	 * @param left 列表元素类型
	 * @param right 数组元素类型
	 * @return R array
	 * @deprecated replace by {@link #to(Object, Type, Type, ContextProvider...)}
	 */
	@SuppressWarnings("unchecked")
	public <L,R> R[] toArray(List<L> input,Class<L> left,Class<R> right){
		if(null == input){
			return null;
		}
		List<R> r = to(input,left,right);
		return r.toArray((R[]) Array.newInstance(right, r.size()));
	}
	/**
	 * 将 列表 转换为数组
	 * @param input
	 * @param left 列表元素类型
	 * @param right 数组元素类型
	 * @return R array
	 * @deprecated replace by {@link #to(Object, Type, Type, ContextProvider...)}
	 */
	@SuppressWarnings("unchecked")
	public <L,R> R[] toArray(L[] input,Class<L> left,Class<R> right){
		if(null == input){
			return null;
		}
		List<R> r = to(input,left,right);
		return r.toArray((R[]) Array.newInstance(right, r.size()));
	}
	/**
	 * 将 Integer 列表 转换为数组
	 * @param input
	 * @param left 
	 * @param right 
	 * @return int array
	 * @deprecated replace by {@link #to(Object, Type, Type, ContextProvider...)}
	 */
	public  int[] tointArray(List<Integer> input,Class<Integer> left,Class<Integer> right){
		return collection2intArray.apply(input);
	}
	/**
	 * 将 Long 列表 转换为数组
	 * @param input
	 * @param left 
	 * @param right 
	 * @return long array
	 * @deprecated replace by {@link #to(Object, Type, Type, ContextProvider...)}
	 */
	public  long[] tolongArray(List<Long> input,Class<Long> left,Class<Long> right){
		return collection2longArray.apply(input);
	}
	/**
	 * 将 Double 列表 转换为数组
	 * @param input
	 * @param left 
	 * @param right 
	 * @return double array
	 * @deprecated replace by {@link #to(Object, Type, Type, ContextProvider...)}
	 */
	public double[] todoubleArray(List<Double>input,Class<Double> left,Class<Double> right){
		return collection2doubleArray.apply(input);	
	}
	/**
	 * 将 Double 列表 转换为float数组
	 * @param input
	 * @param left 
	 * @param right 
	 * @return float array
	 * @deprecated replace by {@link #to(Object, Type, Type, ContextProvider...)}
	 */
	public float[] tofloatArray(List<Double>input,Class<Double> left,Class<Float> right){
		return collection2floatArray.apply(input);
	}
	/**
	 * 将 Short 列表 转换为数组
	 * @param input
	 * @param left 
	 * @param right 
	 * @return short array
	 * @deprecated replace by {@link #to(Object, Type, Type, ContextProvider...)}
	 */
	public short[] toshortArray(List<Short>input,Class<Short> left,Class<Short> right){
		return collection2shortArray.apply(input);	
	}
	/**
	 * 将 Boolean 列表 转换为数组
	 * @param input
	 * @param left 
	 * @param right 
	 * @return boolean array
	 * @deprecated replace by {@link #to(Object, Type, Type, ContextProvider...)}
	 */
	public boolean[] tobooleanArray(List<Boolean>input,Class<Boolean> left,Class<Boolean> right){
		return collection2booleanArray.apply(input);
	}
	/**
	 * 将 Boolean 列表 转换为数组
	 * @param input
	 * @param left 
	 * @param right 
	 * @return boolean array
	 * @since 4.4.0
	 * @deprecated replace by {@link #to(Object, Type, Type, ContextProvider...)}
	 */
	public byte[] tobyteArray(List<Byte>input,Class<Byte> left,Class<Byte> right){
		return collection2byteArray.apply(input);
	}

	/**
	 * 将{@code Map<K1,V1>}转换为{@code Map<K2,V2>}
	 * @param input
	 * @param k1
	 * @param v1
	 * @param k2
	 * @param v2
	 * @return Map instance transformed
	 * @deprecated replace by {@link #to(Object, Type, Type, ContextProvider...)}
	 */
	@SuppressWarnings("unchecked")
	public <K1,V1,K2,V2> Map<K2,V2> to(Map<K1,V1>input,Class<K1>k1,Class<V1>v1,Class<K2> k2,Class<V2> v2){
		checkArgument(null != k1 && null != v1 && null != k2 && null != v2,"k1,v1,k2,v2 must not be null");
		if(k1 == k2){
			if(v1 == v2){
				return (Map<K2, V2>) input;
			}
			return (Map<K2, V2>) Maps.transformValues(input, this.getTransformerChecked(v1, v2));
		}else{
			Map<K2, V1> k2v1 = transform(input,this.getTransformerChecked(k1, k2));
			if(v1 == v2){
				return (Map<K2, V2>) k2v1;
			}else{
				return Maps.transformValues(k2v1, this.getTransformerChecked(v1, v2));
			}
		}		
	}
	/**
	 * 将{@code Map<K1,V1>}转换为{@code Map<K2,V2>}
	 * @param input
	 * @param k1
	 * @param v1
	 * @param k2
	 * @param v2
	 * @return Map instance transformed
	 * @deprecated replace by {@link #to(Object, Type, Type, ContextProvider...)}
	 */
	@SuppressWarnings("unchecked")
	public <K1,V1,K2,V2> Map<K2,V2> to(Map<K1,V1>input,Type k1,Type v1,Type k2,Type v2){
		checkArgument(null != k1 && null != v1 && null != k2 && null != v2,"k1,v1,k2,v2 must not be null");
		if(k1 == k2){
			if(v1 == v2){
				return (Map<K2, V2>) input;
			}
			return (Map<K2, V2>) Maps.transformValues(input, this.getTransformerChecked(v1, v2));
		}else{
			Map<K2, V1> k2v1 =transform(input,(Function<K1, K2>)this.getTransformerChecked(k1, k2));
			if(v1 == v2){
				return (Map<K2, V2>) k2v1;
			}else{
				return Maps.transformValues(k2v1, (Function<V1, V2>)this.getTransformerChecked(v1, v2));
			}
		}		
	}
	/**
	 * 将{@code value}转换为{@code right}指定的类型
	 * @param value
	 * @param left {@code value}的原类型
	 * @param right 目标类型
	 * @return R instance
	 * @deprecated replaced by {@link #to(Object, Type, Type, ContextProvider...)}
	 */
	public <L, R> R cast(Object value, Type left, Type right) {
		return to(value, left, right);
	}

	/**
	 * 创建空的容器对象(如List,Set,Map,Array等)<br>
	 * 比如：
	 * <pre>{@code
	 *     int[] array = emptyContainer(int[].class);
	 *     List<String> list = emptyContainer(new TypeToken<List<String>>(){});
	 *     Map<String,Integer> map = emptyContainer(new TypeToken<Map<String,Integer>>(){});
	 * }</pre>
	 * 对于泛型容器类型 ({@code List,Set,Map}) 也可以直接提供类型参数，如：
	 * <pre>{@code
	 *     List<String> list = emptyContainer(List.class);
	 *     Map<String,Integer> map = emptyContainer(Map.class);
	 *     Set<Integer> set = emptyContainer(Set.class);
	 * }</pre>
	 * @param containerType 容器类型，如 {@code int[].class}, {@code List<String>}, {@code Map<String,Integer>}
	 * @return 空的容器对象
	 * @since 4.4.0
	 */
	@SuppressWarnings({ "unchecked", "serial" })
	protected <C,E> C emptyContainer(TypeToken<C> containerType) {
		TypeToken<E> elementType = (TypeToken<E>) elementTypeOf(containerType, true);
		if(elementType.isPrimitive()){
			/** java 基本类型不能作为泛型类型参数，所以需要使用包装类型 */
			elementType = (TypeToken<E>) TypeToken.of(Primitives.wrap(elementType.getRawType()));
		}
		TypeToken<List<E>> inputType = new TypeToken<List<E>>(){}.where(new TypeParameter<E>() {}, elementType);
		return (C) to(Collections.emptyList(), inputType, null, containerType);
	}
	/**
	 * 创建指定类型的空对象 
	 * @param <C>
	 * @param type
	 * @param throwfUnsupported 当{@code type}不支持创建空对象时，是否抛出异常
	 * @since 4.4.0
	 */
	@SuppressWarnings("unchecked")
	public <C> C emptyOf(TypeToken<C> type, boolean throwfUnsupported) {
		Class<?> rawType = type.getRawType();
		if(CharSequence.class.isAssignableFrom(rawType)){
			return (C) "";
		}else if(isContainerType(type)){
			return (C) emptyContainer(type);
		}
		if(throwfUnsupported) {
			throw new IllegalArgumentException("Unsupported type: "+ type + " to create empty object");
		}
		return null;
	}
	/**
	 * 根据元素类型创建一个数组类型<br>
	 * 如果 {@code componentType}为 {@link Class}则返回数组类型，否则返回泛型数组类型 {@link GenericArrayType}
	 * 
	 * @param componentType
	 */
	private static TypeToken<?> arrayTypeOf(final TypeToken<?> componentType) {
		Type arrayType;
		if(componentType.getRawType() instanceof Class){
			arrayType = Array.newInstance((Class<?>)componentType.getRawType(), 0).getClass();
		}else{
			arrayType = new GenericArrayType() {
				@Override
				public Type getGenericComponentType() {
					return componentType.getType();
				}
			};
		}
		return TypeToken.of(arrayType);
	}
	/**
	 * 创建空的容器对象(如List,Set,Map,Array等)
	 * @param containerType 
	 * @since 4.4.0
	 * @see #emptyContainer(TypeToken)
	 */
	@SuppressWarnings("unchecked")
	protected <C> C emptyContainer(Type containerType) {
		return emptyContainer((TypeToken<C>)TypeToken.of(containerType));
	}
	/**
	 * 返回buffer中所有字节(position~limit),不改变buffer状态
	 * @param buffer
	 * @return buffer 为 null 时返回 null 
	 */
	protected static final byte[] getBytesInBuffer(ByteBuffer buffer){
		if(null == buffer){
			return null;
		}
		int pos = buffer.position();
		try{
			byte[] bytes = new byte[buffer.remaining()];
			buffer.get(bytes);
			return bytes;
		}finally{
			buffer.position(pos);
		}
	}
	/**
	 * 返回buffer中所有字符(position~limit),不改变buffer状态
	 * @param buffer
	 * @return buffer 为 null 时返回 null 
	 */
	protected static final char[] getCharsInBuffer(CharBuffer buffer){
		if(null == buffer){
			return null;
		}
		int pos = buffer.position();
		try{
			char[] chars = new char[buffer.remaining()];
			buffer.get(chars);
			return chars;
		}finally{
			buffer.position(pos);
		}
	}
	/**
	 * 输入的整型值转为无符号的long,非整型参数返回{@code null}
	 * @param input
	 * @since 4.4.0
	 */
	public static Long asUnsignedLong(Object input) {
		if(input instanceof Long){
			return (Long)input;
		}else if(input instanceof Integer) {
			return ((Integer)input).longValue()&0xffffffff;
		}else if(input instanceof Short) {
			return ((Short)input).longValue()&0xffff;
		}else if(input instanceof Byte) {
			return ((Byte)input).longValue()&0xff;
		}else if(input instanceof AtomicLong){
			return ((AtomicLong)input).longValue();
		}else if(input instanceof AtomicInteger){
			return ((AtomicInteger)input).longValue()&0xffffffff;
		}else  if(input instanceof Number) {
			return ((Number)input).longValue();
		}
		return null;
	}
	/**
	 * 输入的整型值转为无符号的long,非整型参数抛出异常
	 * @param input
	 * @since 4.4.0
	 */
	public static long asUnsignedLongChecked(Object input) {
		Long m = asUnsignedLong(input);
		checkArgument(null!=m,"Integral type required for mask");
		return m;
	}
	/** 
	 * convert {@code Map<K1,V>} to {@code Map<K2,V>}
	 * @return {@linkplain ImmutableMap}
	 */
	public static final <K1,K2,V>Map<K2,V> transform(Map<K1,V>fromMap,final Function<K1,K2>transformer){
	    checkNotNull(fromMap,"fromMap is null");
	    checkNotNull(transformer,"transformer is null");
	    // 新的Map对象Key类型已经是K2了，只是Value类型成了Entry
	    ImmutableMap<K2, Entry<K1, V>> k2Entry = Maps.uniqueIndex(fromMap.entrySet(), new Function<Entry<K1, V>,K2>(){
	        @Override
	        public K2 apply(Entry<K1, V> input) {
	            return transformer.apply(input.getKey());
	        }});
	    // 再做一次转换将Entry<K1, V>转换成V,这个过程并没有创建新的Map,只是创建了k2Entry的代理对象
	    Map<K2, V> k2V = Maps.transformEntries(k2Entry, new EntryTransformer<K2,Entry<K1,V>,V>(){
	        @Override
	        public V transformEntry(K2 key, Entry<K1, V> value) {
	            return value.getValue();
	        }});
	    return k2V;
	}
	/**
	 * 将 {@code input} 转换为数组<br>
	 * 
	 * @param input 输入迭代器对象
	 * @param componentType  {@code input}的元素类型
	 * @since 4.4.0
	 */
	@SuppressWarnings({ "unchecked", "rawtypes" })
	static protected Object toArray(Iterable input, Class componentType) {
		if (null == input) {
			return null;
		}
		if (!componentType.isPrimitive()) {
			/** 转换为数组类型 */
			return Iterables.toArray(input, componentType);
		}
		Class<?> primitiveType = Primitives.unwrap(componentType);
		if (int.class == primitiveType) {
			return Ints.toArray(asCollection(input, Number.class));
		}
		if (long.class == primitiveType) {
			return Longs.toArray(asCollection(input, Number.class));
		}
		if (double.class == primitiveType) {
			return Doubles.toArray(asCollection(input, Number.class));
		}
		if (float.class == primitiveType) {
			return Floats.toArray(asCollection(input, Number.class));
		}
		if (short.class == primitiveType) {
			return Shorts.toArray(asCollection(input, Number.class));
		}
		if (byte.class == primitiveType) {
			return Bytes.toArray(asCollection(input, Number.class));
		}
		if (boolean.class == primitiveType) {
			return Booleans.toArray(asCollection(input, Boolean.class));
		}
		if (char.class == primitiveType) {
			return Chars.toArray(asCollection(input, Character.class));
		}
		// DEAD CODE
		throw new UnsupportedOperationException(String.format("unsupported cast %s to %s", componentType, primitiveType));
	}
	
	private static ImmutableSet<Class<?>> EXCLUDE_CONTAINER_TYPES = ImmutableSet.<Class<?>>builder()
		.add(Path.class).build();
	/**
	 * 判断 {@code type} 是否实现了容器类型(Map,Iterable,Multimap,Multiset)接口，但不是容器类型<br>
	 * 有的类型虽然实现了容器类型(Map,Iterable,Multimap,Multiset)接口，但是实际上并不是容器类型，
	 * 比如Path，实现了Iterable接口，但是并不是容器类型。
	 * 此时需要排除掉这些类型，避免转换错误。
	 * @param type
	 * @return 如果假容器类型返回{@code true},否则返回{@code false}
	 */
	protected static boolean isFakeContainerType(Class<?> type){
		if(EXCLUDE_CONTAINER_TYPES.contains(type)){
			return true;
		}
		for(Class<?> excludeType : EXCLUDE_CONTAINER_TYPES){
			if(excludeType.isAssignableFrom(type)){
				return true;
			}
		}
		return false;
	}	
	protected static boolean isContainerType(TypeToken<?> type){
		Class<?> rawType = type.getRawType();
		if(isFakeContainerType(rawType)){
			return false;
		}
		return Map.class.isAssignableFrom(rawType) || Iterable.class.isAssignableFrom(rawType) || Multimap.class.isAssignableFrom(rawType) || Multiset.class.isAssignableFrom(rawType) || rawType.isArray();
	}
	public static boolean isContainerType(Type type){
		return isContainerType(TypeToken.of(type));
	}
	/**
	 * 计算 {@code left} 和 {@code right} 的匹配分值<br>
	 * 分值计算规则如下：<br>
	 * <ul>
	 * <li>如果 {@code right}和 {@code left} 类型相同，则分值为 4</li>
	 * <li>如果 {@code right}或 {@code left} 是原始类型，且对应的原始类型相同，则分值为 3</li>
	 * <li>如果 {@code right}是 {@code left} 的父类型，则分值为 2</li>
	 * <li>否则，分值为 0</li>
	 * </ul>
	 * @param left
	 * @param right
	 */
	protected static int computeMatchScore(TypeToken<?> left, TypeToken<?> right) {
		if(left.equals(right)){
			return 4;
		}
		if (left.isPrimitive() || right.isPrimitive()) {
			if(Primitives.unwrap(left.getRawType()) == Primitives.unwrap(right.getRawType())) {
				return 3;
			}else {
				return 0;
			}
		}
		if(left.isSubtypeOf(right)){
			return 2;
		}
		return 0;
	}
	/**
	 * 返回非{@code null}的可迭代对象 {@link Iterable}
	 * 
	 * @param input 输入对象,输入为 {@code null}时返回空的 {@link Iterable}
	 * @param elementType 元素类型,不为 {@code null}时返回 {@link Iterable} 的元素类型为 {@code elementType}
	 * @return 可迭代对象 {@link Iterable}
	 * @since 4.4.0
	 */
	@SuppressWarnings({ "rawtypes" })
	protected static Iterable asIterable(Object input,Class<?> elementType) {
		if (input == null) {
			return Collections.emptyList();
		}
		if (input instanceof Iterable) {
			return (Iterable) input;
		} else if (input instanceof Map) {
			/** Map类型的leftType为Map.Entry<K,V> */
			return (Iterable) ((Map) input).entrySet();
		}  else if (input instanceof Multimap) {
			/** Map类型的leftType为Map.Entry<K,V> */
			return (Iterable) ((Multimap) input).entries();
		} else if (input.getClass().isArray()) {
			Class<?> componentType = input.getClass().getComponentType();
			if(elementType == null || isAssignable(elementType, componentType)){
				/** primitive类型数组转为List */
				if (input.getClass().getComponentType() == int.class) {
					return Ints.asList((int[]) input);
				} else if (input.getClass().getComponentType() == long.class) {
					return Longs.asList((long[]) input);
				} else if (input.getClass().getComponentType() == double.class) {
					return Doubles.asList((double[]) input);
				} else if (input.getClass().getComponentType() == float.class) {
					return Floats.asList((float[]) input);
				} else if (input.getClass().getComponentType() == short.class) {
					return Shorts.asList((short[]) input);
				} else if (input.getClass().getComponentType() == boolean.class) {
					return Booleans.asList((boolean[]) input);
				} else if (input.getClass().getComponentType() == byte.class) {
					return Bytes.asList((byte[]) input);
				} else if (input.getClass().getComponentType() == char.class) {
					return Chars.asList((char[]) input);
				} else {
					return Arrays.asList((Object[]) input);
				}

			}
		}
		throw new IllegalArgumentException("input is not Iterable,we can not transform to Iterable<" + elementType == null ? "Object" : elementType.getName() + ">");
	}

	/**
	 * 判断 {@code from} 是否可以赋值给 {@code to}
	 */
	protected static boolean isAssignable(TypeToken<?> from, TypeToken<?> to) {
		return computeMatchScore(from, to) > 0;
	}

	/**
	 * 判断 {@code from} 是否可以赋值给 {@code to}
	 */
	protected static boolean isAssignable(Type from, Type to) {
		return isAssignable(TypeToken.of(from), (TypeToken.of(to)));
	}

	/**
	 * 判断 {@code from} 是否可以赋值给 {@code to},且 {@code from}, {@code to} 都不是原始类型
	 */
	protected static boolean isNoPrimitiveAssignable(TypeToken<?> from, TypeToken<?> to) {
		int score = computeMatchScore(from, to);
		return score == 4 || score == 2;
	}

	/**
	 * Returns the owner type of a {@link ParameterizedType} or enclosing class of a {@link Class},
	 * or null otherwise.
	 */
	private static Type getOwnerTypeIfPresent(TypeToken<?> typeToken) {
		Type runtimeType = typeToken.getType();
		if (runtimeType instanceof ParameterizedType) {
			return ((ParameterizedType) runtimeType).getOwnerType();
		} else if (runtimeType instanceof Class<?>) {
			return ((Class<?>) runtimeType).getEnclosingClass();
		} else {
			return null;
		}
	}

	/**
	 * 返回 以 {@link Map.Entry} 为元素的容器类型(如{@link Map} 或 {@link Multimap}) 的元素类型，
	 * 如果{@code containerType}不是{@link Class}或{@link ParameterizedType}则抛出 {@link IllegalArgumentException}
	 * @param containerType
	 * @param superType {@code containerType}的超类或实现的接口
	 * @return {@code Map.Entry<K,V>} 类型
	 * @since 4.4.0
	 */
	private static Type entryElementType(TypeToken<?> containerType, Class<?> superType) {
		if(containerType.getType() instanceof ParameterizedType) {
			ParameterizedType parameterizedType = (ParameterizedType) containerType.getType();
			return new ParameterizedTypeImpl(Map.Entry.class, parameterizedType.getActualTypeArguments(),
					getOwnerTypeIfPresent(containerType));
		}else if(containerType.getType() instanceof Class) {
			Type[] typeArgs = getTypeArguments(containerType, superType);
			/** Map类型的元素类型为Map.Entry<K,V> */
			return new ParameterizedTypeImpl(Map.Entry.class, typeArgs,
					getOwnerTypeIfPresent(containerType));
		}
		throw new IllegalArgumentException("unsupported type: " + containerType.getType());
	}

	/**
	 * 返回 {@code containerType}的类型参数数组，
	 * 如果{@code containerType}不是{@link Class}或{@link ParameterizedType}则抛出 {@link IllegalArgumentException}
	 * @param containerType
	 * @param superType {@code containerType}的超类或实现的接口
	 * @return 类型参数数组
	 */
	private static Type[] getTypeArguments(TypeToken<?> containerType, Class<?> superType) {
		if(containerType.getType() instanceof ParameterizedType) {
			ParameterizedType parameterizedType = (ParameterizedType) containerType.getType();
			return parameterizedType.getActualTypeArguments();
		}else if(containerType.getType() instanceof Class) {
			TypeVariable<?>[] typevars = containerType.getRawType().getTypeParameters();
			Type[] superTypevars;
			if (typevars.length == 0 && (superTypevars = superType.getTypeParameters()).length!=0) {
				/** 
				 * Class.getTypeParameters() 返回的是声明的类型参数，
				 * 没有返回类型参数的情况下，使用 TypeToken.resolveType方法解析 superType的参数变量获取元素类型
				 * 比如 java.nio.Path 实现了 Iterable<Path>,但是没有返回类型参数，
				 * 所以需要使用 TypeToken.resolveType方法解析 Path的参数变量获取元素类型,
				 * 类似的例子还有 java.util.Properties 实现了 Map<Object,Object>,但是没有返回类型参数。
				 */
				Type[] resolvedTypes = new Type[superTypevars.length];
				for (int i = 0; i < superTypevars.length; i++) {
					resolvedTypes[i] = containerType.resolveType(superTypevars[i]).getType();
				}
				return resolvedTypes;
			}else {
				return typevars;
			}
		}
		throw new IllegalArgumentException("unsupported type: " + containerType.getType());
	}

	/**
	 * 返回容器类型 {@code containerType}的元素类型,如果不是容器类型则抛出 {@link UnsupportedOperationException}
	 * @param containerType 容器类型 
	 * @param throwfUnsupported 当{@code containerType}不支持创建空对象时，是否抛出异常,为{@code false}时返回{@code null}
	 */
	protected static TypeToken<?> elementTypeOf(TypeToken<?> containerType, boolean throwfUnsupported) {
		Type elementType = null;
		if(isFakeContainerType(containerType.getRawType())) {
			/** 非容器类型 */
			// DO NOTHING
		} else if (containerType.isSubtypeOf(Iterable.class)) {
			/** Iterable类型的元素类型为唯一的类型参数 */
			elementType = getTypeArguments(containerType, Iterable.class)[0];
		} else if (containerType.isSubtypeOf(Map.class)) {
			elementType = entryElementType(containerType, Map.class);
		} else if (containerType.isSubtypeOf(Multimap.class)) {
			elementType = entryElementType(containerType, Multimap.class);
		} else if(containerType.isArray()){
			/** 数组类型的元素类型为数组元素类型 */
			elementType = containerType.getComponentType().getType();
		} 
		if(null == elementType && throwfUnsupported) {
			throw new UnsupportedOperationException("unsupported container type: " + containerType);				
		}
		return null == elementType ? null : TypeToken.of(elementType);
	}

	/**
	 * 将 {@code iterable} 转换为 {@code elementType}指定的类型集合
	 * @param <T>
	 * @param iterable
	 * @param elementType
	 * @since 4.4.0
	 */
	@SuppressWarnings({ "unchecked", "rawtypes" })
	protected static<T> Collection<T> asCollection(Iterable iterable,Class<T> elementType) {
		if (iterable instanceof Collection) {
			return (Collection<T>) iterable;
		}
		return Lists.newArrayList(iterable);
	}
	/**
	 * 断言当 {@code type} 是primitive类型时 {@code value} 不为 {@code null}
	 * 否则抛出 {@link IllegalArgumentException}<br>
	 * @param value 要检查的值
	 * @param type  要检查的类型
	 */
	private static <V> V checkNotNullForPrimitive(V value, TypeToken<?> type) {
		checkArgument(null != value || !type.isPrimitive(), "cant cast null to primitive type %s", type);
		return value;
	}
	/**
	 * 断言当 {@code type} 是primitive类型时 {@code value} 不为 {@code null}
	 * 否则抛出 {@link IllegalArgumentException}<br>
	 * @param value 要检查的值
	 * @param type  要检查的类型
	 */
	private static <V> V checkNotNullForPrimitive(V value, Type type) {
		checkArgument(null != value || !(type instanceof Class<?>) || !((Class<?>) type).isPrimitive(),
				"cant cast null to primitive type %s", type);
		return value;
	}

	/**
	 * 计算 {@code left -> rowKey} 和 {@code right -> columnKey} 的匹配分值<br>
	 * 分值计算规则如下：<br>
	 * <ul>
	 * <li>如果 {@code right}和 {@code columnKey} 类型相同，且 {@code left}和 {@code rowKey}
	 * 类型相同，则分值为 4</li>
	 * <li>如果 {@code right}和 {@code columnKey} 类型相同，且 {@code rowKey}是 {@code left}
	 * 的父类型，则分值为 3</li>
	 * <li>如果 {@code right}是 {@code columnKey} 的父类型，且 {@code left}和 {@code rowKey}
	 * 类型相同，则分值为 2</li>
	 * <li>如果 {@code right}是 {@code columnKey} 的父类型，且 {@code rowKey}是 {@code left}
	 * 的父类型，则分值为 1</li>
	 * <li>否则，分值为 0</li>
	 * </ul>
	 * 
	 * @param left      需要转换的左侧类型
	 * @param right     需要转换的右侧类型
	 * @param rowKey    左侧类型对应的转换表中的行键
	 * @param columnKey 右侧类型对应的转换表中的列键
	 * @return 匹配分值
	 */
	private static int computeMatchScore(TypeToken<?> left, TypeToken<?> right, TypeToken<?> rowKey,
			TypeToken<?> columnKey) {
		if (right.equals(columnKey) && left.equals(rowKey)) {
			return 4;
		}
		if (right.isPrimitive()) {
			right = TypeToken.of(Primitives.wrap(right.getRawType()));
		}
		if (left.isPrimitive()) {
			left = TypeToken.of(Primitives.wrap(left.getRawType()));
		}
		// if (columnKey.isPrimitive()) {
		// columnKey = TypeToken.of(Primitives.wrap(columnKey.getRawType()));
		// }
		// if (rowKey.isPrimitive()) {
		// rowKey = TypeToken.of(Primitives.wrap(rowKey.getRawType()));
		// }
		if (columnKey.equals(right) && rowKey.equals(left)) {
			return 4;
		}
		if (columnKey.equals(right) && rowKey.isSupertypeOf(left)) {
			return 3;
		}
		if (isTypeMatch(right, columnKey) && rowKey.equals(left)) {
			return 2;
		}
		if (isTypeMatch(right, columnKey) && rowKey.isSupertypeOf(left)) {
			return 1;
		}
		return 0;
	}
	/**
	 * 判断 right 是否匹配 columnKey 的类型（支持通配符类型）
	 * 规则：
	 * 1. 如果 columnKey 是 ? extends T，则 right 必须是 T 或 T 的子类
	 * 2. 如果 columnKey 是 ? super T，则 right 必须是 T 或 T 的父类
	 * 3. 其他类型直接使用 isSupertypeOf 判断
	 */
	private static boolean isTypeMatch(TypeToken<?> right, TypeToken<?> columnKey) {
		Type type = columnKey.getType();

		// 处理通配符类型 ? extends T
		if (type instanceof WildcardType) {
			WildcardType wildcard = (WildcardType) type;
			Type[] upperBounds = wildcard.getUpperBounds();
			Type[] lowerBounds = wildcard.getLowerBounds();

			// 处理 ? extends T
			if (upperBounds.length > 0 && lowerBounds.length == 0) {
				TypeToken<?> bound = TypeToken.of(upperBounds[0]);
				return right.isSubtypeOf(bound);
			}

			// 处理 ? super T
			if (lowerBounds.length > 0 && upperBounds.length == 0) {
				TypeToken<?> bound = TypeToken.of(lowerBounds[0]);
				return bound.isSubtypeOf(right);
			}
            // 处理复杂的通配符类型（如果有多个上界或下界）
            for (Type upperBound : upperBounds) {
                if (!isTypeMatch(TypeToken.of(upperBound), right)) {
                    return false;
                }
            }
            for (Type lowerBound : lowerBounds) {
                if (!isTypeMatch(right, TypeToken.of(lowerBound))) {
                    return false;
                }
            }
		}

		// 默认逻辑：right 是 columnKey 的父类
		return right.isSupertypeOf(columnKey);
	}
	/**
	 * copy from {@code com.gitee.l0km.com4j.basex.bean.BaseBeanPropertySupport#isEmpty(Object) }<br> 
	 * 判断输入参数是否为{@code null}或空<br>
	 * 如果输入参数为@{@link String},{@link Collection},{@link Iterable},{@link Iterator},{@link Map},数组等容器类型则返回其是否为空,
	 * 否则返回{@code false}
	 * @param value 为{@code null}返回{@code true}
	 * @since 4.4.0
	 */
	public static boolean isEmpty(Object value){
		if(null == value){
			return true;
		}else if(value instanceof String){
			return ((String)value).isEmpty();
		}else if(value instanceof CharSequence){
			return ((CharSequence)value).length() == 0;
		}else if (value instanceof Collection) {
			return ((Collection<?>)value).isEmpty();
		}else if (value instanceof Iterator) {
			return !((Iterator<?>)value).hasNext();
		}else if (value instanceof Iterable) {
			return !((Iterable<?>)value).iterator().hasNext();
		}else if (value instanceof Enumeration) {
			return !((Enumeration<?>)value).hasMoreElements();
		}else if (value instanceof Map) {
			return ((Map<?, ?>)value).isEmpty();
		}else if (value instanceof Multimap) {
			// GUAVA type
			return ((Multimap<?, ?>)value).isEmpty();
		}else if (value instanceof Multiset) {
			// GUAVA type
			return ((Multiset<?>)value).isEmpty();
		}else if (value instanceof Optional) {
			// GUAVA type
			return isEmpty(((Optional<?>)value).orNull());
		}else if (value.getClass().isArray()) {
			return Array.getLength(value) == 0;
		}
		return false;
	}
	/**
	 * 数据类型转换器抽象类<br>
	 * 用于将 {@code input}转换为指定的类型<br>
	 * 
	 * @param <F> 输入类型
	 * @param <T> 输出类型
	 * @since 4.4.0
	 */
	public static abstract class BaseFunction<F, T> implements Function<F, T> {
		protected final BaseTypeTransformer typeTransformer;
		/** 内置输入特性，用于子类定义对输入值的预处理，参见 {@link Empty2NullFunction} */
		protected final ContextProvider inputFeature;
		protected final ContextProvider feature;
		protected final LocalContext builtinInputContext;
		protected final LocalContext localContext;
		/** 输入类型 {@code F} */
		protected final TypeToken<F> inputType;
		/** 输出类型 {@code T} */
		protected final TypeToken<T> outputType;
		/** 
		 * 是否对输入容器类型进行过滤<br>
		 * 为 {@code true}时,对输入的容器类型进行过滤<br>
		 * 为 {@code false}时,对输出容器类型进行过滤<br>
		 * 参见 {@link ContainerTransformer},{@link Iterable2PrimitiveArrayFunction}
		 */
		private final boolean runFilter4InputIfContainer;
		
		@SuppressWarnings("serial")
		protected BaseFunction(BaseTypeTransformer typeTransformer, ContextProvider inputFeature,
				ContextProvider feature, boolean runFilter4InputIfContainer) {
			this.typeTransformer = typeTransformer;
			this.inputFeature = inputFeature;
			this.feature = ContextContainer.merge(typeTransformer.context, feature);
			/**
			 * 将输入类型变量 {@code F}和输出类型变量 {@code T} 解析为具体类型, 参见
			 * https://blog.csdn.net/10km/article/details/145321422
			 */
			this.inputType = new TypeToken<F>(getClass()) {};
			this.outputType = new TypeToken<T>(getClass()) {};
			this.runFilter4InputIfContainer = runFilter4InputIfContainer;
			this.builtinInputContext = inputFeature.getContext().buildLocalContext(typeTransformer, inputType,
					elementTypeOf(inputType, false));
			this.localContext = buildOuputLocalContext(feature);
		}

		protected BaseFunction(BaseTypeTransformer typeTransformer) {
			this(typeTransformer, Feature.DEFAULT, Feature.DEFAULT, false);
		}

		private BaseFunction(BaseTypeTransformer typeTransformer, ContextProvider inputFeature, ContextProvider feature,
				TypeToken<F> leftType, TypeToken<T> rightType, boolean runFilter4InputIfContainer) {
			this.typeTransformer = typeTransformer;
			this.inputFeature = inputFeature;
			this.feature = ContextContainer.merge(typeTransformer.context, feature);
			this.inputType = leftType;
			this.outputType = rightType;
			this.runFilter4InputIfContainer = runFilter4InputIfContainer;
			this.builtinInputContext = inputFeature.getContext().buildLocalContext(typeTransformer, inputType,
					elementTypeOf(inputType, false));
			this.localContext = buildOuputLocalContext(feature);
		}

		@SuppressWarnings("unchecked")
		protected BaseFunction(BaseTypeTransformer typeTransformer, Type leftType, Type rightType) {
			this(typeTransformer, Feature.DEFAULT, Feature.DEFAULT, (TypeToken<F>)TypeToken.of(leftType),(TypeToken<T>) TypeToken.of(rightType), false);
		}

		protected BaseFunction(BaseTypeTransformer typeTransformer, TypeToken<F> leftType, TypeToken<T> rightType) {
			this(typeTransformer, Feature.DEFAULT, Feature.DEFAULT, leftType, rightType, false);
		}

		/**
		 * 执行数据类型转换<br>
		 * 
		 * @param input        非{@code null}输入值
		 * @param ltx          本地上下文
		 * @param thisFun 当前转换器对象，一般情况下，该就是当前对象，但是对于代理转换器，该参数为代理转换器对象，参见
		 *                     {@link #replaceOutputTypeNoEqual(TypeToken, TypeToken)}
		 * @return 转换后的输出值
		 * @throws Exception 转换过程可能抛出的异常
		 */
		protected abstract T doApply(F input, LocalContext ltx, BaseFunction<?, ?> thisFun) throws Exception;

		public final T apply(F input) {
			return apply(input, localContext);
		}
		private final T apply(F input, ContextProvider ctx){
			return apply(input, buildOuputLocalContext(ctx));
		}

		@SuppressWarnings({ "unchecked" })
		protected final T apply(F input, LocalContext ltx) {
			/**
			 * 根据输入上下文 {@code builtinInputContext} 对输入执行格式化，
			 * 比如：{@link Empty2NullFunction}要求输入为 {@code null}或空时返回 {@code null}
			 */
			F _input = formatValue(input, builtinInputContext, inputType, true);
			if (runFilter4InputIfContainer) {
				/**
				 * 如果 {@code runFilter4InputIfContainer} 为 {@code true}则对输入的容器类型进行过滤,
				 * 执行转换后就不再对输出容器类型进行过滤
				 */
				_input = filterElementIfContainer(_input, ltx.getElementFilter(), inputType);
			}
			T output;
			if (null == _input) {
				/** 输入为 {@code null} 时不执行转换 */
				output = ltx.nullOrPlaceholderOnNull();
			} else if (isDirectConvertible()) {
				/** 输入类型与输出类型相同或其父类型或实现的接口,直接强制转换 */
				output = (T) _input;
			} else {
				try {
					/** 输入类型不为 {@code null} 且与输出类型不同,执行转换 */
					output = doApply(_input, ltx, this);
				} catch (Exception e) {
					/** 处理 doApply 方法抛出的异常 */
					output = ltx.onTransformError(_input, e);
				}
			}
			/**
			 * 对输出值使用 {@code ltx}上下文进行格式化，
			 * 如果执行转换前没有对输入执行元素过滤({@code runFilter4InputIfContainer}为
			 * {@code false}),则转换后对输出容器类型执行过滤
			 */
			return formatValue(output, ltx, outputType, !runFilter4InputIfContainer);
		}

		private LocalContext buildOuputLocalContext(ContextProvider provider) {
			return provider.getContext().buildLocalContext(typeTransformer, outputType,
					runFilter4InputIfContainer ? elementTypeOf(inputType, false) : elementTypeOf(outputType, false));
		}

		/**
		 * 判断 {@code input}是否可以直接强制转换为 {@code T}类型
		 * 即输出类型与输入类型相同或其父类型或实现的接口
		 */
		private final boolean isDirectConvertible() {
			return inputType.isSubtypeOf(outputType);
		}

		/**
		 * 如果 {@code input}为容器类型,则对 {@code value}中的元素执行过滤<br>
		 * @param <V>
		 * @param value
		 * @param elementFilter 元素过滤器
		 * @param valueType 容器元素类型
		 */
		@SuppressWarnings({ "rawtypes", "unchecked" })
		private final <V> V filterElementIfContainer(V value, Predicate elementFilter, TypeToken<?> valueType) {
			if(null != value && elementFilter != null && isContainerType(valueType)) {
				/**
				 * 如果 {@code output}是容器类型,且 {@link LocalContext#getElementFilter()} 不为 {@code null}
				 * 则对容器元素进行过滤,并转换为 {@code outputType}指定的类型
				 * 否则直接返回 {@code output}
				 */
				TypeToken<?> elementType = elementTypeOf(valueType, true);
				FluentIterable filtered = FluentIterable.from(asIterable(value, elementType.getRawType())).filter(elementFilter);
				value = typeTransformer.to(filtered, TypeToken.of(of(Iterable.class, elementType.getType())), null, valueType);
			}
			return value;
		}

		/**
		 * 根据本地上下文 {@code localContext} 对 {@code value} 进行格式化<br>
		 * 如果 {@code localContext}所有字段都为 {@code null},则直接返回 {@code value}<br>
		 */
		private <V> V formatValue(V value, LocalContext localContext, TypeToken<?> valueType, boolean runFilter) {
			if(!localContext.isNull()){
				if (value == null) {
					value = localContext.nullOrPlaceholderOnNull();
				} else if (isEmpty(value)) {
					value = localContext.emptyOrPlaceholderOnEmpty(value);
				}
				if(runFilter) {
					value = filterElementIfContainer(value,	localContext.getElementFilter(), valueType);
				}
			}
			return value;
		}
		/**
		 * 当输出类型不匹配时，替换输出类型<br>
		 * 
		 * 此方法用于在特定条件下替换当前函数的输出类型:<br>
		 * 如果当前函数的输出类型与指定的右类型不匹配，
		 * 且当前输出类型属于Class类型或WildcardType类型，则创建并返回一个新的BaseFunction实例，
		 * 其输出类型被替换为指定的右值类型,
		 * 如果类型匹配或不符合替换条件，则返回当前函数实例不变<br>
		 * 支持对WildcardType类型的原因是为了支持 {@link #outputType} 为通配符类型定义的子类型(如 ? extends Number)的情况,
		 * 参见 {@link Date2SubTransformer#doApply(Date, LocalContext, BaseFunction)} <br>
		 * NOTE: 泛型类暂时没有需要替换类型的需求，因此对于支持泛型类(除 WildcardType 外)的转换器直接返回当前对象
		 * @param left  左值类型
		 * @param right 右值类型
		 * @return 如果输出类型不匹配且符合替换条件，则返回新的BaseFunction实例；否则返回当前实例
		 */
		private BaseFunction<F, T> replaceOutputTypeNoEqual(TypeToken<F> left, TypeToken<T> right) {
		    // 检查建议的输出类型是否与当前输出类型不匹配，且当前输出类型为Class类型或WildcardType类型
		    if (!right.equals(this.outputType) && (this.outputType.getType() instanceof Class
		            || this.outputType.getType() instanceof WildcardType)) {
		        // 创建并返回一个新的BaseFunction实例，带有替换的输出类型
		        return new BaseFunction<F, T>(typeTransformer, inputFeature, feature, left, right,
		                runFilter4InputIfContainer) {
		
		            @Override
		            protected T doApply(F input, LocalContext ltx, BaseFunction<?, ?> thisFun) throws Exception {
		                // 调用原始函数实例的doApply方法执行逻辑
						// NOTE: 这里 thisFun不是当前实例，而是新的匿名内部类的实例
		                return BaseFunction.this.doApply(input, ltx, this);
		            }
		        };
		    }
		    // 如果输出类型匹配或不符合替换条件，返回当前函数实例
		    return this;
		}

		/**
		 * 判断 {@code fun}是否为 {@link BaseFunction}的子类,如果是,则返回调用
		 * {@link BaseFunction#replaceOutputTypeNoEqual(TypeToken, TypeToken)} 方法<br>
		 * 否则,将 {@code fun}包装为 {@link BaseFunction}对象并返回<br>
		 * 
		 * @param typeTransformer
		 * @param left
		 * @param right
		 * @param fun
		 * @see #replaceOutputTypeNoEqual(TypeToken, TypeToken)
		 */
		@SuppressWarnings({ "rawtypes", "unchecked" })
		private static BaseFunction wrap(BaseTypeTransformer typeTransformer, TypeToken left, TypeToken right,
				final Function fun) {
			if (fun instanceof BaseFunction) {
				return ((BaseFunction) fun).replaceOutputTypeNoEqual(left, right);
			}
			return new BaseFunction(typeTransformer, Feature.DEFAULT, Feature.DEFAULT, left, right, false) {

				@Override
				protected Object doApply(Object input, LocalContext ltx, BaseFunction thisFun) throws Exception {
					return fun.apply(input);
				}
			};
		}

		@Override
		public String toString() {
			StringBuilder builder = new StringBuilder();
			builder.append("BaseFunction [inputFeature=").append(inputFeature).append(", feature=").append(feature)
					.append(", inputType=").append(inputType).append(", outputType=").append(outputType).append("]");
			return builder.toString();
		}

	}

	/**
	 * {@link Function}的抽象实现，用于将 {@code input}转换为指定的类型<br>
	 * 如果 {@code input}为 {@code null}或空，则返回 {@code null}<br>
	 * 
	 * @param <F> 输入类型
	 * @param <T> 输出类型
	 * @since 4.4.0
	 */
	public static abstract class Empty2NullFunction<F, T> extends BaseFunction<F, T> {
		protected Empty2NullFunction(BaseTypeTransformer typeTransformer) {
			super(typeTransformer, Feature.EMPTY_TO_NULL, Feature.DEFAULT, false);
		}
		protected Empty2NullFunction(BaseTypeTransformer typeTransformer, TypeToken<F> leftType, TypeToken<T> rightType) {
			super(typeTransformer, Feature.EMPTY_TO_NULL, Feature.DEFAULT, leftType, rightType, false);
		}
	}

	/**
	 * {@link Function}的抽象实现，用于将boolean类型转换为指定的数字类型<br>
	 * 如果 {@code input}为 {@code null}或空，则返回 {@code null}<br>
	 * 
	 * @param <N> 输出类型
	 * @since 4.4.0
	 */
	public static abstract class BooleanToNumber<N extends Number> extends BaseFunction<Boolean, N> {
		protected BooleanToNumber(BaseTypeTransformer typeTransformer) {
			super(typeTransformer);
		}
	
		@SuppressWarnings("unchecked")
		@Override
		protected N doApply(Boolean input, LocalContext ltx, BaseFunction<?, ?> thisFun) {
			return (N) typeTransformer.to(input ? 1 : 0, int.class, outputType.getRawType());
		}
	}

	/**
	 * 数字到枚举类型转换
	 * 
	 * @param <E> 枚举类型
	 * @since 4.4.0
	 */
	public static class Number2Enum<E extends Enum<E>> extends BaseFunction<Number, E> {
		final Class<E> enumType;

		public Number2Enum(BaseTypeTransformer typeTransformer, Class<E> enumType) {
			super(typeTransformer, Number.class, enumType);
			this.enumType = checkNotNull(enumType, "enumType is null");
		}

		@Override
		public E doApply(Number input, LocalContext ltx, BaseFunction<?, ?> thisFun) {
			return enumType.getEnumConstants()[input.intValue()];
		}
	}

	/**
	 * 字符串到枚举类型转换
	 * 
	 * @param <E> 枚举类型
	 * @since 4.4.0
	 */
	public static class String2Enum<E extends Enum<E>> extends Empty2NullFunction<String, E> {
		final Class<E> enumType;

		public String2Enum(BaseTypeTransformer typeTransformer, Class<E> enumType) {
			super(typeTransformer, TypeToken.of(String.class), TypeToken.of(enumType));
			this.enumType = checkNotNull(enumType, "enumType is null");
		}

		@Override
		public E doApply(String input, LocalContext ltx, BaseFunction<?, ?> thisFun) {
			return Enum.valueOf(enumType, input);
		}
	}
	/**
	 * 用于将包含基本类型元素的容器类型({@link Iterable}) 转换为指定的基本类型数组<br>
	 * 比如 {@code List<Integer>} 转换为 {@code int[]}<br>
	 * 
	 * @param <F> 输入类型
	 * @param <T> 输出类型
	 */
	@SuppressWarnings("rawtypes")
	public static abstract class Iterable2PrimitiveArrayFunction<F extends Iterable, T> extends BaseFunction<F, T> {
		protected Iterable2PrimitiveArrayFunction(BaseTypeTransformer typeTransformer) {
			/**
			 * runFilter4InputIfContainer 为true, 指定对输入的容器类型进行过滤, 以适应不允许 {@code null}元素的 primitive 数组类型
			 */
			super(typeTransformer, Feature.DEFAULT, Feature.DEFAULT, true);
		}
	}

	/**
	 * 类名到类的转换器<br>
	 * 用于将字符串类型的类名转换为 {@link Class}对象<br>
	 * 
	 * @since 4.4.0
	 */
	public static class ClassName2ClassFunction extends Empty2NullFunction<String, Class<?>> {
		protected static final Map<String, Class<?>> PRIMITIVE_NAME_MAP = ImmutableMap.<String, Class<?>>builder()
				.put("int", int.class).put("short", short.class).put("byte", byte.class).put("long", long.class)
				.put("double", double.class).put("float", float.class).put("char", char.class)
				.put("boolean", boolean.class).put("void", void.class).put("Integer", Integer.class)
				.put("Short", Short.class).put("Byte", Byte.class).put("Long", Long.class).put("Double", Double.class)
				.put("Float", Float.class).put("Character", Character.class).put("Boolean", Boolean.class)
				.put("Void", Void.class).build();
		protected final boolean initialize;
		protected final ClassLoader classLoader;
	
		protected ClassName2ClassFunction(BaseTypeTransformer typeTransformer, boolean initialize, ClassLoader classLoader) {
			super(typeTransformer);
			this.initialize = initialize;
			this.classLoader = classLoader;
		}
	
		protected ClassName2ClassFunction(BaseTypeTransformer typeTransformer, ClassLoader classLoader) {
			this(typeTransformer, false, classLoader);
		}
	
		protected ClassName2ClassFunction(BaseTypeTransformer typeTransformer) {
			this(typeTransformer, false, null);
		}
	
		protected ClassLoader getClassLoader() {
			return classLoader;
		}
	
		@Override
		protected Class<?> doApply(String input, LocalContext ltx, BaseFunction<?, ?> thisFun) throws ClassNotFoundException {
			Class<?> clazz = PRIMITIVE_NAME_MAP.get(input);
			if (clazz != null) {
				return clazz;
			}
			if (null != classLoader) {
				clazz = Class.forName(input, initialize, classLoader);
			}
			return Class.forName(input);
		}
	}
	/**
	 * 容器类型(List,Set,Map,Array)构造器抽象类<br>
	 * 用于从可迭代对象 {@link Iterable}读取元素 {@code L}，转换为指定类型 {@code R},并构造容器对象
	 * {@code C}的容器对象,将转换后的元素放入容器中
	 * 
	 * @param <I> 输入类型
	 * @param <C> 容器类型
	 * @since 4.4.0
	 */
	@SuppressWarnings("rawtypes")
	static class ContainerTransformer<I,C> extends BaseFunction<I,C> {
		/**
		 * 接口容器类型到实例化容器类型的映射表
		 */
		protected static final ImmutableMap<Class<?>, Class<?>> INSTANTIABLE_CONTAINER_TYPES = ImmutableMap.<Class<?>, Class<?>>builder()
				.put(Collection.class, ArrayList.class)
				.put(Set.class, HashSet.class)
				.put(List.class, ArrayList.class)
				.put(Map.class, HashMap.class)
				.put(Iterable.class, ArrayList.class)
				.put(SortedSet.class, TreeSet.class)
				.put(SortedMap.class, TreeMap.class)
				.put(NavigableSet.class, TreeSet.class)
				.put(NavigableMap.class, TreeMap.class)
				.put(ConcurrentMap.class,ConcurrentHashMap.class)
				.put(ConcurrentNavigableMap.class,ConcurrentSkipListMap.class)
				.build();
		protected final TypeToken<?> leftElementType;
		protected final TypeToken<?> rightElementType;
		protected final Class<?> containerType;

		@SuppressWarnings("unchecked")
		protected ContainerTransformer(BaseTypeTransformer typeTransformer, TypeToken<I> left, TypeToken<C> containerType) {
			/**
			 * runFilter4InputIfContainer 为true, 指定对输入的容器类型进行过滤, 以适应不允许 {@code null}元素的容器类型，比如 {@link ImmutableList}
			 */
			super(typeTransformer, Feature.DEFAULT, Feature.DEFAULT, determineContainerSupertype(left), containerType, true);
			this.leftElementType = elementTypeOf(left, true);
			this.rightElementType = elementTypeOf(containerType, true);
			this.containerType = Primitives.wrap(outputType.getRawType());
		}

		/**
		 * 返回非{@code null}的左侧元素的可迭代对象 {@link Iterable}
		 * 
		 * @param input 输入对象,输入为 {@code null}时返回空的 {@link Iterable}
		 * @return 可迭代对象 {@link Iterable}
		 */
		@SuppressWarnings({ "unchecked" })
		protected Iterable getIterableLeft(Object input) {
			if (input == null) {
				return Collections.emptyList();
			}
			/** 
			 * 优先尝试从根据类型查找匹配的转换器，如果找到则调用转换器转换为 Iterable，
			 * 所以如果在转换表中预定义了转换器，则会被优先使用
			 */
			Function transformer = typeTransformer.getTransformer0(input.getClass(), of(Iterable.class, leftElementType.getType()),false);
			if (transformer != null) {
				return (Iterable) transformer.apply(input);
			}
			/** 
			 * 如果没有找到匹配的转换器，则尝试调用 {@link #asIterable(Object, Class)}方法中获取可迭代对象
			 */
			try {
				return asIterable(input, leftElementType.getRawType());
			} catch (IllegalArgumentException e) {
				throw new IllegalArgumentException(e.getMessage() + ", you must override getIterableLeft()");
			}
		}

		protected Map<Class<?>, Class<?>> getInstantiableContainerTypes() {
			return INSTANTIABLE_CONTAINER_TYPES;
		}

		/**
		 * 返回实例化容器类型的Class对象<br>
		 * 优先从 {@link #getInstantiableContainerTypes()}中获取容器类型对应的实例化类型，如果没有，则返回容器类型本身
		 * 如果容器类型是接口类型或抽象类，则抛出异常<br>
		 * @return 实例化容器类型的Class对象
		 */
		protected Class<?> getInstantiableContainerClass() {
			Class<?> instantiable = getInstantiableContainerTypes().get(containerType);
			if (instantiable != null) {
				return instantiable;
			}
			if (containerType.isInterface()) {
				throw new UnsupportedOperationException("unsupported interface type as container type: " + containerType);
			}
			if (Modifier.isAbstract(containerType.getModifiers())) {
				throw new UnsupportedOperationException("abstract class can not be instantiated: " + containerType);
			}
			return containerType;
		}

		/**
		 * 创建实例化容器对象<br>
		 * 调用 {@link #getInstantiableContainerClass()}获取实例化容器类型，然后调用默认构造器创建实例化对象
		 * @return 实例化容器对象
		 */
		protected Object buildContainer() {
			try {
				return getInstantiableContainerClass().getConstructor().newInstance();
			} catch (InstantiationException | IllegalAccessException | IllegalArgumentException
					| InvocationTargetException | NoSuchMethodException | SecurityException e) {
				Throwables.throwIfUnchecked(e);
				throw new RuntimeException(e);
			}
		}
		static final ImmutableList<Class<?>> CONTAINER_SUPERTYPES = ImmutableList.<Class<?>>builder()
			.add(Set.class)
			.add(List.class)
			.add(Collection.class)
			.add(Iterable.class)
			.add(Map.class)
			.add(Multiset.class)
			.add(Multimap.class)
			.build();

		/**
		 * 获取容器类型的有效父接口类型（用于元素过滤场景）<br>
		 * 
		 * 该方法通过以下逻辑确定容器类型：<br>
		 * 1. 当容器类型可实例化（存在无参构造器）时，直接返回原类型<br>
		 * 2. 当容器类型不可实例化时，遍历预定义的容器接口集合（{@link #CONTAINER_SUPERTYPES}）<br>
		 *    找到最接近的父接口类型作为实际处理类型<br>
		 * 
		 * 比如，Arrays.asList()返回的List类型是不可变的，在对该类型的容器执行元素过滤后无法创建容器对象，
		 * 所以需要计算输入类型实现的容器接口类型作为输入类型
		 * 
		 * @param type 待分析的容器类型
		 * @return 优先返回可实例化的容器类型，否则返回其实现的容器接口类型。
		 *         若输入类型不符合容器类型条件，直接返回原类型
		 */
		@SuppressWarnings("unchecked")
		private static TypeToken determineContainerSupertype(TypeToken type) {
			if (!type.isArray() && isContainerType(type)) {
				Class<?> containerType = type.getRawType();
				try {
					/** 如果输入类型是可实例化的，则返回输入类型，否则计算输入类型实现的容器接口类型作为输入类型 */
					containerType.getConstructor();
				} catch (NoSuchMethodException | SecurityException e) {
					for (Class<?> superType : CONTAINER_SUPERTYPES) {
						if (superType.isAssignableFrom(containerType)) {
							if (superType.equals(containerType)) {
								break;
							}
							return type.getSupertype(superType);
						}
					}
				}
			}
			return type;
		}
		/**
		 * 创建Guava的容器对象<br>
		 * 调用 {@link #buildContainer()}获取实例化容器对象，然后调用Guava的容器工厂方法创建容器对象，
		 * 并将转换后的元素放入容器中<br>
		 * 如果容器类型不是Guava的容器类型，则返回null
		 * 
		 * @param iterable 右侧元素的可迭代对象 {@link Iterable}
		 * @return Guava的只读容器对象
		 */
		@SuppressWarnings("unchecked")
		protected Object buildGuavaContainer(Iterable iterable) {
			if (ImmutableMap.class.equals(containerType)) {
				return ImmutableMap.copyOf((Iterable<Map.Entry<?, ?>>) iterable);
			} else if (ImmutableSet.class.equals(containerType)) {
				return ImmutableSet.copyOf(iterable);
			} else if (ImmutableList.class.equals(containerType)) {
				return ImmutableList.copyOf(iterable);
			} else if (ListMultimap.class.equals(containerType)) {
				return ImmutableListMultimap.copyOf(iterable);
			} else if (SetMultimap.class.equals(containerType)) {
				return ImmutableSetMultimap.copyOf(iterable);
			} else if (Multiset.class.equals(containerType)) {
				return ImmutableMultiset.copyOf(iterable);
			} else if (Multimap.class.equals(containerType)) {
				return ImmutableMultimap.copyOf((Iterable<Map.Entry<?, ?>>) iterable);
			} else if (ImmutableMultimap.class.equals(containerType)) {
				return ImmutableMultimap.copyOf((Iterable<Map.Entry<?, ?>>) iterable);
			} else if (ImmutableMultiset.class.equals(containerType)){
				return ImmutableMultiset.copyOf(iterable);
			} else if (SortedMultiset.class.equals(containerType)) {
				return ImmutableSortedMultiset.copyOf(iterable);
			} else if (ImmutableSortedMap.class.equals(containerType)) {
				return ImmutableSortedMap.copyOf((Iterable<Map.Entry<?, ?>>) iterable);
			} else if (BiMap.class.equals(containerType)) {
				return ImmutableBiMap.copyOf((Iterable<Map.Entry<?, ?>>) iterable);
			} else if (ImmutableBiMap.class.equals(containerType)) {
				return ImmutableBiMap.copyOf((Iterable<Map.Entry<?, ?>>) iterable);
			} 
			return null;
		}
		/**
		/**
		 * 返回添加了left元素后的容器对象 {@code C}
		 * 
		 * @param iterableRight 元素类型为容器元素类型({@link #rightElementType})的可迭代对象 {@link Iterable}
		 * @return 包含目标容器元素的容器对象 {@code C}
		 */
		@SuppressWarnings("unchecked")
		protected Object build(Iterable iterableRight) {
			Object container = buildGuavaContainer(iterableRight);
			if (container != null) {
				return container;
			}
			if(containerType.isArray()){
				return toArray(iterableRight, rightElementType.getRawType());
			}
			container = buildContainer();
			if (container instanceof Collection) {
				/** Iterable 接口类型有对应的可实例化Collection类型 */
				Iterables.addAll((Collection) container, iterableRight);
			} else if (container instanceof Map) {
				/** 
				 * iterableRight 元素类型为Map.Entry<K,V>
				 * 参见 {@link #getIterableLeft(Object)} 方法中对Map类型的处理
				 * 这里直接将Map.Entry<K,V>放入Map中
				 */
				for (Map.Entry entry : (Iterable<Map.Entry>) iterableRight) {
					((Map) container).put(entry.getKey(), entry.getValue());
				}
			} else {
				throw new UnsupportedOperationException("unsupported collection type: " + container.getClass());
			}
			return container;
		}

		@SuppressWarnings("unchecked")
		@Override
		public C doApply(I input, LocalContext ltx, BaseFunction<?, ?> thisFun) {
			return (C) build(to(getIterableLeft(input), leftElementType, rightElementType));
		}
		/**
		 * 将 Iterable 中的元素转换为{@code right}指定的类型，
		 * @param input
		 * @param leftElementType 列表元素原类型
		 * @param rightElementType 列表元素目标类型
		 * @return 转换后的元素 {@link Iterable}
		 * @since 4.4.0
		 */
		@SuppressWarnings("unchecked")
		private <L,R>Iterable<R> to(Iterable<L> input,TypeToken<?> leftElementType, TypeToken<?> rightElementType){
			if (null == input) {
				return null;
			}
			if (isNoPrimitiveAssignable(leftElementType, rightElementType)) {
				return (Iterable<R>) input;
			} else {
				return (Iterable<R>) Iterables.transform(input,
						typeTransformer.getTransformerChecked(leftElementType.getType(), rightElementType.getType()));
			}
		}
	}

	/**
	 * {@link java.util.Map.Entry}转换器<br>
	 * 用于将 {@link java.util.Map.Entry}的Key和Value转换为 {@code leftEntryType}和 {@code rightEntryType}指定的类型
	 */
	public static class GenericEntryTransformer extends BaseFunction<Map.Entry<?,?>, Map.Entry<?,?>> {
		private final Type leftKeyType;
		private final Type leftValueType;
		private final Type rightKeyType;
		private final Type rightValueType;
	
		public GenericEntryTransformer(BaseTypeTransformer typeTransformer, ParameterizedType leftEntryType, ParameterizedType rightEntryType) {
			super(typeTransformer, leftEntryType, rightEntryType);
			this.leftKeyType = leftEntryType.getActualTypeArguments()[0];
			this.leftValueType = leftEntryType.getActualTypeArguments()[1];
			this.rightKeyType = rightEntryType.getActualTypeArguments()[0];
			this.rightValueType = rightEntryType.getActualTypeArguments()[1];
		}
		
		@Override
		public Entry<?, ?> doApply(Entry<?, ?> input, LocalContext ltx, BaseFunction<?, ?> thisFun) {
			return new SimpleImmutableEntry<>(typeTransformer.to(input.getKey(), leftKeyType, rightKeyType),
					typeTransformer.to(input.getValue(), leftValueType, rightValueType));
		}
	}

	/**
	 * 将 {@code input}分割转换为指定的容器类型的转换器<br>
	 * 通过{@code L --> Iterable<L> --> Iterable<E>}间接转换实现，
	 * 实现的前提是子类要提供{@code L --> Iterable<L>}的分割转换器<br>
	 * 比如 {@code input}为 {@code String}，如果提供了{@code String --> List<String>}的转换器，
	 * 就可以实现 {@code String --> List<Date>},{@code String --> List<File>},{@code String --> Interger[]}的转换<br>
	 * 如果 {@code input}为 {@code null}或空，则返回 {@code null}<br>
	 * 
	 * @param <L> 输入类型
	 * @param <R> 输出容器类型, 如 List, Set, Map, Array
	 * @since 4.4.0
	 */
	protected static class SplitTransformer<L,R> extends BaseFunction<L, R> {

		protected SplitTransformer(BaseTypeTransformer typeTransformer) {
			super(typeTransformer);
		}
		protected SplitTransformer(BaseTypeTransformer typeTransformer, Type leftType, Type rightType) {
			super(typeTransformer, leftType, rightType);
		}
		protected SplitTransformer(BaseTypeTransformer typeTransformer, TypeToken<L> leftType, TypeToken<R> rightType) {
			super(typeTransformer, leftType, rightType);
		}

		/** <pre>{@code inputType -> Iterable<inputType> -> outputType}</pre> */
		@Override
		protected R doApply(L input, final LocalContext ltx, BaseFunction<?, ?> thisFun) throws Exception {
			/**
			 * 如果有过滤器，则对输出执行过滤
			 */
			ContextProvider[] contextProviders = new ContextProvider[0];
			if (null != ltx.getElementFilter()) {
				contextProviders = new ContextProvider[] { new TransformerContext() {
					@Override
					public <T, E> Predicate<T> elementFilter(BaseTypeTransformer typeTransformer,
							TypeToken<E> elementType) {
						return ltx.getElementFilter();
					}
				} };
			}
			return typeTransformer.to(input, inputType, TypeToken.of(of(Iterable.class, inputType.getType())),
					outputType, contextProviders);
		}
	}

	/**
	 * 动态类型转换器，根据输入对象的实际类型执行到目标类型的动态转换
	 *
	 * @since 4.4.0
	 * @param <R> 转换器输出的目标类型
	 */
	protected static class DynamicTransformer<R> extends BaseFunction<Object, R> {

		/**
		 * 构造动态类型转换器
		 *
		 * @param typeTransformer 底层类型转换器实例
		 * @param rightType       目标类型的类型令牌，用于指定转换目标类型
		 */
		protected DynamicTransformer(BaseTypeTransformer typeTransformer, TypeToken<R> rightType) {
			super(typeTransformer, TypeToken.of(Object.class), rightType);
		}

		@SuppressWarnings("unchecked")
		@Override
		public R doApply(Object input, LocalContext ltx, BaseFunction<?, ?> thisFun) {
			/*
			 * 防御性检查：当输入类型为Object.class时直接拒绝转换 Object作为所有类的父类无法安全向下转型，此检查可防止类型转换器进入无限递归
			 */
			checkArgument(input.getClass() != Object.class, "can't transform Object to %s", outputType);

			/*
			 * 动态类型转换核心逻辑： 1. 获取输入对象的实际运行时类型 2. 使用底层转换器执行具体类型转换
			 */
			return (R) typeTransformer.to(input, TypeToken.of((Class<Object>) input.getClass()), outputType);
		}
	}
	/**
	 * 日期转换器，将Date转换为子类Date的转换器
	 * @param <T> 目标类型
	 */
	private static class Date2SubTransformer<T extends Date> extends BaseFunction<Date, T> {
	    
		private Date2SubTransformer(BaseTypeTransformer transformer) {
			/** right为 WildcardType: ? extend Date */
			super(transformer, Date.class, new WildcardTyper.SubOf<Date>() {}.wildcardType);
	    }

	    @SuppressWarnings("unchecked")
		@Override
	    public T doApply(Date input, LocalContext ltx, BaseFunction<?, ?> thisFun) throws Exception{
			/** 
			 * 因为 this.outputType为 WildcardType: ? extend Date,并不能代表真正的目标类型
			 * 所以这里要使用 thisFun.outputType.getRawType()来获取目标类型
			 * {@link BaseFunction#replaceOutputTypeNoEqual(TypeToken, TypeToken)}方法会基于当前对象封装一个新的转换器，
			 * 新转换器中的outputType为具体的目标类型
			 */
	    	return (T) thisFun.outputType.getRawType().getConstructor(long.class).newInstance(input.getTime());
	    }

	}
	/**
	 * 枚举类型转换
	 *
	 * @param <L> 输入枚举类型
	 * @param <R> 输出枚举类型
	 * @since 4.4.0
	 */
	public static class EnumTransformer<L extends Enum<L>,R extends Enum<R>> implements Function<L,R>{
		private final Class<R> right;
		public EnumTransformer(Class<L> left, Class<R> right) {
			checkNotNull(left,"left is null");
			this.right = checkNotNull(right,"right is null");
		}
		@Override
		public R apply(L input) {
			return null == input ? null : Enum.valueOf(right, input.name());
		}    	
	}
	
	
	/**
	 * （非静态）转换类，用于简化泛型类型对象的转换逻辑
	 * <p>使用示例：</p>
	 * <pre>{@code
	 * // 创建BaseTypeTransformer实例
	 * BaseTypeTransformer transformer = new BaseTypeTransformer();
	 * 
	 * // 通过匿名类实现具体转换逻辑
	 * Multiset<Class<?>> result = transformer.new Fun<List<String>, Multiset<Class<?>>>(){}.apply(inputList);
	 * }</pre>
	 * @param <L> 输入类型
	 * @param <R> 输出类型
	 * @since 4.4.0
	 */
	public class Fun<L, R> implements Function<L, R> {
		private final Type leftType;
		private final Type rightType;

		/**
		 * <p>
		 * 构造函数，用于初始化Fun类的实例。
		 * </p>
		 * <p>
		 * 该构造函数会获取当前类的泛型超类，并对其进行检查。
		 * </p>
		 * <ul>
		 * <li>若无法获取泛型超类，将抛出{@link IllegalArgumentException}异常。</li>
		 * <li>若泛型超类不是{@link ParameterizedType}类型，也将抛出{@link IllegalArgumentException}异常。</li>
		 * </ul>
		 * <p>
		 * 若检查通过，会从泛型超类中提取实际类型参数，并分别赋值给{@code leftType}和{@code rightType}。
		 * </p>
		 */
		protected Fun() {
			Type superClass = getClass().getGenericSuperclass();
			if (null == superClass) {
				throw new IllegalArgumentException("FAILED TO get generic super class");
			}
			if (!(superClass instanceof ParameterizedType)) {
				throw new IllegalArgumentException("super class is not ParameterizedType");
			}
			ParameterizedType parameterizedType = (ParameterizedType) superClass;
			Type[] actualTypeArguments = parameterizedType.getActualTypeArguments();
			leftType = actualTypeArguments[0];
			rightType = actualTypeArguments[1];
		}

		public Fun(Class<L> leftClass, Class<R> rightClass) {
			leftType = checkNotNull(leftClass, "leftClass is null");
			rightType = checkNotNull(rightClass, "rightClass is null");
		}

		@SuppressWarnings("unchecked")
		@Override
		public final R apply(L input) {
			if (null == input) {
				/**
				 * 检查目标类型是否为基本类型，若为基本类型，抛出 {@link IllegalArgumentException}异常。
				 */
				checkNotNullForPrimitive(input, rightType);
				return null;
			}
			if (isAssignable(leftType, rightType)) {
				return (R) input;
			}
			return BaseTypeTransformer.this.to(input, leftType, null, rightType);
		}
	}
}
